簡體   English   中英

通用對象的通用列表

[英]Generic list of generic objects

假設我有一個表示數據字段的對象,該對象需要以下屬性:名稱、類型、值、長度。 這是對象:

class Field<T>
{
    public string Name { get; set; }
    public Type Type
    {
        get
        {
            return typeof(T);
        }
    }
    public int Length { get; set; }
    public T Value { get; set; }
}  

我使用了泛型,因為我想強制代碼的用戶只能分配某個類型的值。
現在的問題是當我想創建一個字段列表時。
如果我創建像List<Field<object>>這樣的List<Field<object>>那么我們可以為列表中的給定 Field 分配任何值,當我們查詢 Type 時,我們會得到“object”。
問題是 - 在該列表中,我可能想要很少的字段保存字符串,很少保存整數、日期,甚至自定義對象,而這些自定義對象又將具有字段列表...
泛型是解決此類問題的好方法嗎? 如果是,我將如何實施它? 如果沒有,什么是更好的方法?

---編輯---
只是添加一些更多的背景:
1. 我可能想要一個字段列表,每個字段將保存不同的數據類型,如下所示:

List<Field<object>> lst = new List<Field<object>>();
lst.Add(new Field<string>());
lst.Add(new Field<int>());
lst.Add(new Field<SomeObjectFromMyApp>());

2.稍后我將不得不在循環中自動查詢這些對象及其屬性,如下所示:

foreach(Field<object> fld in lst)
{
    Type t = fld.Type;
    //do some other stuff
}

是的,泛型是一個不錯的選擇。 實現類型安全(並使用Type屬性標識類型)的關鍵是在列表和Field<T>類之間添加抽象。

Field<T>實現接口IField 這個接口不需要任何成員。

然后將您的列表聲明為List<IField>

這樣您就可以將列表限制為僅包含字段,但每個字段可以是不同的類型。

要稍后讀取值,只需執行

foreach(var field in list)
{
    var type = field.Type;
    ....
}

我建議您定義一個接口, Field<T>實現該接口

public interface IField
{

}

public class Field<T> : IField
{
    public string Name { get; set; }
    public Type Type
    {
        get
        {
            return typeof(T);
        }
    }
    public int Length { get; set; }
    public T Value { get; set; }
}

所以你可以寫這個代碼:

var list = new List<IField>();

現在這個列表可以包含任何Field<T>類型的對象

正如一些評論者已經提到的,如果您創建一個空的接口,您將無法訪問Type屬性,所以我寧願這樣做:

public interface IField
{
    Type Type { get; }

    string Name { get; set; }

    int Length { get; set; }
}

public class Field<T> : IField
{
    public string Name { get; set; }

    Type IField.Type => typeof(T);

    public int Length { get; set; }

    public T Value { get; set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

然后您可以檢查 value 屬性是哪種數據類型並將對象強制轉換為正確的類型:

class Program
{
    static void Main(string[] args)
    {
        var fieldList = new List<IField>()
        {
            new Field<string>()
            {
                Value = "Hello World!", 
                Length = 12, 
                Name = "A string"
            },
            new Field<int>()
            {
                Value = 4711,
                Length = sizeof(int),
                Name = "An integer value"
            },
            new Field<double>()
            {
                Value = 2.4,
                Length = sizeof(double),
                Name = "A double value"
            },
        };

        foreach (var field in fieldList)
        {
            if (field.Type == typeof(string))
            {
                PrintField(field, "String value:");
            }
            else if (field.Type == typeof(int))
            {
                PrintField(field, "Integer value:");
            }
            else if (field.Type == typeof(double))
            {
                PrintField(field, "Double value:");
            }
        }
    }

    static void PrintField(IField field, string info)
    {
        Debug.WriteLine(info);
        Debug.WriteLine($"\tName: {field.Name}, Length: {field.Length}, Value: {field}");
    }
}

該代碼產生以下輸出:

// String value:
//  Name: A string, Length: 12, Value: Hello World!
// Integer value:
//     Name: An integer value, Length: 4, Value: 4711
// Double value:
//     Name: A double value, Length: 8, Value: 2,4

暫無
暫無

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

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