C# 在调用中向泛型传递对象的类型

C# 在调用中向泛型传递对象的类型,c#,generics,C#,Generics,我看过其他几个类似的帖子,但它们似乎不符合我的设想 我试图创建一组深度克隆方法,将其用于从基类继承的一组对象。我创建了一些示例类来说明我要做的事情 我已经阅读了这里所有类似的帖子和MS文档,但似乎没有任何效果。任何关于如何处理这一问题的建议都将不胜感激 下面是这篇文章中有问题的代码行。使用typeofc是无效的,我找不到任何合适的方法来替换它 SubEvents = (IList<IFoo>) SubEvents.Select(c => c.Clone < typeof(

我看过其他几个类似的帖子,但它们似乎不符合我的设想

我试图创建一组深度克隆方法,将其用于从基类继承的一组对象。我创建了一些示例类来说明我要做的事情

我已经阅读了这里所有类似的帖子和MS文档,但似乎没有任何效果。任何关于如何处理这一问题的建议都将不胜感激

下面是这篇文章中有问题的代码行。使用typeofc是无效的,我找不到任何合适的方法来替换它

SubEvents = (IList<IFoo>) SubEvents.Select(c => c.Clone < typeof(c) > ()).ToList()
我无法找到将对象的类型传递给克隆方法的方法

public class MyFoo : IFoo
{
    public int Id { get; set; }
    public IList<IFoo> SubEvents { get; set; } = new List<IFoo>();

    public T Clone<T>() where T : IFoo, new()
    {
        var rtn = new T
        {
            Id = Id,
            SubEvents = (IList<IMyFoo>) SubEvents.Select(c => c.Clone < typeof(c) > ()).ToList()
        };
        return rtn;
    }
}

public class Bar: Foo, IBar
{
    public int Fred { get; set; }
    public int Betty { get; set; }

    public IEventQuestTimerChange Clone()
    {
        var rtn = base.Clone<Foo>();
        rtn.Fred = Fred;
        rtn.Betty = Betty;
        return rtn;
    }
}

public class Loader
{
    var IList<IFoo> MyList {get;set;} = new List<IFoo>();
    MyList.Add(new Foo());
    var bar = new Bar();
    bar.SubEvent.Add(new Foo());
    bar.SubEvent.Add(new Bar());
    MyList.Add(bar);

    var cloneList = MyList.Clone();
}

你不能像那样将类型传递到泛型中,唯一的方法就是使用反射


而是将重载添加到T Clone。。。对于对象CloneType类型

如果我正确理解了这个问题,那么在clone方法中使用泛型类型的原因是,您可以返回派生类型,而不是基类型

解决这个问题的一种方法是创建一个复制构造函数,以及一个返回派生类型对象的虚拟克隆方法。这样,您就不需要任何泛型来创建深度副本:

    public class Foo
    {
        public int FooProperty { get; }
        public List<Foo> FooList { get; }
        public Foo()
        {
            // Regular Constructor
            FooList = new List<Foo>();
        }
        protected Foo(Foo other)
        {
            // Copy constructor
            FooProperty = other.FooProperty;
            FooList = other.FooList.Select(item => item.Clone()).ToList();
        }

        public virtual Foo Clone() => new Foo(this);
    }

    public class Bar : Foo
    {
        public int BarProperty { get; }
        public Bar()
        {
            // regular constructor
        }
        protected Bar(Bar other) : base(other)
        {
            // Copy constructor
            BarProperty = other.BarProperty;
        }
        public override Foo Clone() => new Bar(this);
        public virtual Bar CloneBar() => new Bar(this);
    }

Will write:Root:Foo->[Bar,Foo]

需要在编译时指定泛型类型,而typeof在运行时检查类型,因此这不起作用。为什么克隆是通用的?IGameEvent似乎与IMyFoo相同。从我所看到的情况来看,假设IMyFoo继承了IGameEvent?我猜您应该将克隆作为扩展方法来实现。当我尝试创建示例时,IGAMeevent有点代码延迟。实际的代码相当大,所以我想把它缩减到一些更易消耗的东西?它是您给定代码中继承的接口,还是您希望转换为的另一个接口?这其实很重要,我的错,我有两个。他们现在都是IFoo。IFoo是Foo的接口。IBar实现/扩展IFoo。我曾尝试过采用这种方法,但从未成功过。我能想到的唯一可行的解决方案是在基类中有一个方法,该方法标识继承它的对象类型,将对象强制转换为该类型,然后调用该cast对象的Clone方法。我之所以提出这个解决方案,是因为我有200多种类型的类继承自IFoo。这些类扩展了Foo类。克隆它们很容易。是Foo中的IFoo对象列表造成了问题,因为我无法确定它是什么类型的对象来调用它的Clone方法。在前面的一篇评论中,我提到一个解决方案是使用一个方法来创建对父对象的硬转换,或者它是基础对象,我有时会在脑海中混淆命名,但这似乎很难处理。我不清楚Item.Clone是如何解决这个问题的。我不确定我是否理解这个问题。它在列表中的对象类型应该无关紧要,只要它是一个返回相同类型的克隆方法。然后由clone方法的实现返回正确派生类型的对象。问题是,在遍历列表时,我无法调用父级的clone方法,因为我的泛型只将is视为类型为Foo的对象,我没有将其视为类型栏或任何其他实现IFoo的类,而是更新了代码以更好地显示我试图描述的内容。Loader方法显示子事件如何具有不同类型对象的列表。克隆调用需要调用每个对象的Clone方法,而不是base Foo的Clone方法。Clone方法是虚拟的并被覆盖,因此如果对象是Bar,Clone将返回一个新的Bar对象。增加了一个例子。
        var root = new Foo();
        root.FooList.Add(new Bar());
        root.FooList.Add(new Foo());
        var clone = root.Clone();
        Console.WriteLine($"Root: {clone.GetType().Name} -> [{clone.FooList[0].GetType().Name}, {clone.FooList[1].GetType().Name}]");