[英]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.