C# 从给定的';基数';对象

C# 从给定的';基数';对象,c#,oop,generics,polymorphism,C#,Oop,Generics,Polymorphism,我有以下课程(非常简化的版本): 公共接口A{} 公共抽象类A:A,其中TType:A { 公开摘要无效初始化(); 公共摘要TType DeepCopy(); public TContentType值{get;private set;} } B级:A级 { public override void Initialise(){this.Value=3.0;} 公共重写B DeepCopy(){返回新的B();} } 公共C类:A { public override void Initialise

我有以下课程(非常简化的版本):

公共接口A{}
公共抽象类A:A,其中TType:A
{
公开摘要无效初始化();
公共摘要TType DeepCopy();
public TContentType值{get;private set;}
}
B级:A级
{
public override void Initialise(){this.Value=3.0;}
公共重写B DeepCopy(){返回新的B();}
}
公共C类:A
{
public override void Initialise(){this.Value='v';}
公共重写C DeepCopy(){返回新的C();}
}
我可以创建一个类型列表,如下所示:

public static List<A> CreateList()
{
    List<A> myList = new List<A>();
    myList.Add(new B());
    myList.Add(new C());
    return myList;
}
公共静态列表CreateList()
{
List myList=新列表();
添加(新的B());
添加(新的C());
返回myList;
}
我想创建一个方法,给定一个类型为a的对象,它将根据指定的长度创建这些对象的列表

例如:

public static List<A> CreateList(A baseA, int length)
{
    List<A> myList = new List<A>();
    for (int i = 0; i < length; i++)
    {
       // create a deep copy of baseA
       // call the Initialise method on the new object
       // add to the list
    }
    return myList;
}
publicstaticlist创建列表(baseA,int-length)
{
List myList=新列表();
for(int i=0;i
我不确定如何在不知道A的类型的情况下创建深度副本,因为A不包含任何内容。。我需要为此创建一个通用方法吗


非常感谢任何指针

没有内置的方法来创建正确的深度副本。需要深度复制的类型应该实现IClonable

您可以从中继承A接口,然后在CreateList中调用Clone(),将其返回值强制转换为所需类型

public interface A: IClonable { 
    Initialize();
}


public static List<A> CreateList(A baseA, int length)
{
    List<A> myList = new List<A>();
    for (int i = 0; i < length; i++)
    {
       var copy = (A) baseA.Clone();
       copy.initialize();
       myList.Add(copy);
    }
    return myList;
}
公共接口A:IClonable{
初始化();
}
公共静态列表CreateList(baseA,int-length)
{
List myList=新列表();
for(int i=0;i

缺点是克隆返回的是对象,而不是继承的类型。但这是框架本身中广泛使用的方法。

您让事情变得相当复杂,首先,您不需要将泛型参数所属的对象类型指定为泛型参数(
TType
),因为我们已经有了这些信息

这里有一个解决方案。它有一个
接口
IA
,上面有一个
IA Clone()
方法。然后我们可以调用该方法,并将其安全性强制转换为
CreateList()
中的
T
CreateList
需要一个您想要的类型的泛型参数,作为
a
/
B
/
C
的泛型参数可以是任何类型

public static List<T> CreateList<T>(T baseA, int length) where T : IA
{
    var myList = new List<T>();
    for (int i = 0; i < length; i++)
    {
        myList.Add((T)baseA.Clone());
    }
    return myList;
}

public interface IA
{
    public abstract IA Clone();
}

public abstract class A<TContentType> : IA
{
    public abstract void Initialise();
    public TContentType Value { get; private set; }
}

public class B : A<double>
{
    public override IA Clone()
    {
        var b = new B();
        // transfer properties
        return b;
    }

    //public override void Initialise() { this.Value = 3.0; }
}

public class C : A<char>
{

    public override IA Clone()
    {
        var c = new C();
        // transfer properties
        return c;
    }

    //public override void Initialise() { this.Value = 'v'; }
}
公共静态列表CreateList(T baseA,int length),其中T:IA
{
var myList=新列表();
for(int i=0;i
只是建议如何使您的方法发挥作用: 如果参数的类型是,那么接口显然必须有DeepCopy()和Initialise()方法。另外,为了让您拥有返回特定类型对象的DeepCopy()方法,您可以使用显式接口实现

public interface A
{
    void Initialise();
    A DeepCopy();
}

public abstract class A<TType, TContentType> : A where TType : A
{
    public abstract void Initialise();
    public abstract TType DeepCopy();
    A A.DeepCopy() { return this.DeepCopy(); }
    public TContentType Value { get; protected set; }
}

public class B : A<B, double>
{
    public override void Initialise() { this.Value = 3.0; }
    public override B DeepCopy() { return new B(); }
}

public class C : A<C, char>
{
    public override void Initialise() { this.Value = 'v'; }
    public override C DeepCopy() { return new C(); }
}

class Program
{
    static void Main(string[] args)
    {
        List<A> listBC = CreateList();
        List<A> list = CreateList(new B(), 3);
    }

    public static List<A> CreateList()
    {
        List<A> myList = new List<A>();
        myList.Add(new B());
        myList.Add(new C());
        return myList;
    }

    public static List<A> CreateList(A baseA, int length)
    {
        List<A> myList = new List<A>(length);

        for (int i = 0; i < length; i++)
        {
            A copy = baseA.DeepCopy();
            copy.Initialise();
            myList.Add(copy);
        }

        return myList;
    }
}
公共接口A
{
无效初始化();
深度复制();
}
公共抽象类A:A,其中TType:A
{
公开摘要无效初始化();
公共摘要TType DeepCopy();
A.DeepCopy(){返回此.DeepCopy();}
公共TContentType值{get;protected set;}
}
B级:A级
{
public override void Initialise(){this.Value=3.0;}
公共重写B DeepCopy(){返回新的B();}
}
公共C类:A
{
public override void Initialise(){this.Value='v';}
公共重写C DeepCopy(){返回新的C();}
}
班级计划
{
静态void Main(字符串[]参数)
{
List listBC=CreateList();
List List=CreateList(新的B(),3);
}
公共静态列表CreateList()
{
List myList=新列表();
添加(新的B());
添加(新的C());
返回myList;
}
公共静态列表CreateList(baseA,int-length)
{
列表myList=新列表(长度);
for(int i=0;i

我不知道您的真实代码,但是
DeepCopy(){returnnewb();}
必须复制一些成员值,对吗?此外,当用副本填充列表时,您真的需要初始化它们还是保留深度副本?

是的,我将复制成员值,这只是一个简化版本。谢谢你的建议。
public interface A
{
    void Initialise();
    A DeepCopy();
}

public abstract class A<TType, TContentType> : A where TType : A
{
    public abstract void Initialise();
    public abstract TType DeepCopy();
    A A.DeepCopy() { return this.DeepCopy(); }
    public TContentType Value { get; protected set; }
}

public class B : A<B, double>
{
    public override void Initialise() { this.Value = 3.0; }
    public override B DeepCopy() { return new B(); }
}

public class C : A<C, char>
{
    public override void Initialise() { this.Value = 'v'; }
    public override C DeepCopy() { return new C(); }
}

class Program
{
    static void Main(string[] args)
    {
        List<A> listBC = CreateList();
        List<A> list = CreateList(new B(), 3);
    }

    public static List<A> CreateList()
    {
        List<A> myList = new List<A>();
        myList.Add(new B());
        myList.Add(new C());
        return myList;
    }

    public static List<A> CreateList(A baseA, int length)
    {
        List<A> myList = new List<A>(length);

        for (int i = 0; i < length; i++)
        {
            A copy = baseA.DeepCopy();
            copy.Initialise();
            myList.Add(copy);
        }

        return myList;
    }
}