簡體   English   中英

從給定的“基礎”對象創建泛型類列表

[英]Create a list of generic classes from a given 'base' object

我有以下課程(非常簡化的版本):

public interface A { }
public abstract class A<TType, TContentType> : A where TType: A
{
    public abstract void Initialise();
    public abstract TType DeepCopy();
    public TContentType Value { get; private 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(); }
}

我可以創建一個A類型的列表,如下所示:

public static List<A> CreateList()
{
    List<A> myList = new List<A>();
    myList.Add(new B());
    myList.Add(new C());
    return 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;
}

我不確定如何在不知道A類型的情況下創建深層副本,因為A不包含任何內容..是否需要為此創建通用方法?

任何指針,不勝感激

您使事情復雜化了很多,首先,您不需要將泛型參數所屬的對象的類型指定為泛型參數( TType ),因為我們已經掌握了這些信息。

這是一個解決方案。 它具有interface IAinterface IA上具有IA Clone()方法。 然后,我們可以調用該方法並將其安全地CreateList()轉換為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'; }
}

只是建議如何工作:如果您的參數類型將為A ,則顯然, A接口必須具有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;
    }
}

我不知道您的真實代碼,但是DeepCopy() { return new B(); } DeepCopy() { return new B(); }必須正確復制一些成員的值? 而且,當在列表中填充副本時,您是否真的需要對它們進行初始化或將深層副本保留原樣?

沒有內置方法可以創建正確的深層副本。 需要深度復制的類型應實現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;
}

缺點是Clone返回對象,而不是您的繼承類型。 但這是框架本身廣泛使用的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM