假设我有一个表示数据字段的对象,该对象需要以下属性:Name,Type,Value,Length。这是对象:
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>>
这样的列表,那么我们可以将任何值分配给列表中的给定字段,当我们查询Type时,我们得到'object'。
事情是 - 在那个列表上我可能想要几个字段持有字符串,少数持有整数,日期,甚至自定义对象,而这些对象又有一个字段列表...
泛型是一个很好的解决方案吗?如果是的话,我将如何实施呢?如果没有,有什么更好的方法?
--- --- EDIT
只是为了增加一些背景:
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
}
答案 0 :(得分:16)
是的,仿制药是个不错的选择。实现类型安全的关键(并且使用Type
属性标识类型是在列表和Field<T>
类之间添加抽象。
让Field<T>
实现接口IField
。该界面不需要任何成员。
然后将您的列表声明为List<IField>
。
这样,您可以将列表限制为仅包含字段,但每个字段可以是不同的类型。
稍后再读取值,只需执行
foreach(var field in list)
{
var type = field.Type;
....
}
答案 1 :(得分:13)
我建议您定义一个接口,Field实现该接口
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>
答案 2 :(得分:0)
正如已经提到的一些注释者一样,如果创建一个空的Interface,则不能访问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();
}
}
然后您可以检查数据属性值属性为,并将对象转换为正确的类型:
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