Kar*_*ahr 8 c# generics reflection
我有一个相当简单的问题,但在C#中似乎没有解决方案.
我有大约100个Foo类,每个类都实现一个static FromBytes()方法.还有一些泛型类应该使用这些方法FromBytes().但是泛型类不能使用这些static FromBytes()方法,因为它们T.FromBytes(...)是非法的.
我是否遗漏了某些内容或者无法实现此功能?
public class Foo1
{
public static Foo1 FromBytes(byte[] bytes, ref int index)
{
// build Foo1 instance
return new Foo1()
{
Property1 = bytes[index++],
Property2 = bytes[index++],
// [...]
Property10 = bytes[index++]
};
}
public int Property1 { get; set; }
public int Property2 { get; set; }
// [...]
public int Property10 { get; set; }
}
//public class Foo2 { ... }
// [...]
//public class Foo100 { ... }
// Generic class which needs the static method of T to work
public class ListOfFoo<T> : System.Collections.Generic.List<T>
{
public static ListOfFoo<T> FromBytes(byte[] bytes, ref int index)
{
var count = bytes[index++];
var listOfFoo = new ListOfFoo<T>();
for (var i = 0; i < count; i++)
{
listOfFoo.Add(T.FromBytes(bytes, ref index)); // T.FromBytes(...) is illegal
}
return listOfFoo;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为,在所有答案和评论以不同的方式对不同的观点做出贡献后,选择答案作为公认的答案是不公平的.如果有人用不同的方法对不同的方法进行了很好的概述,那就太好了.在它帮助未来的开发人员最好之后,应该接受它.
最好的选择是简单地接受特定FromBytes函数作为泛型FromBytes函数的委托.这避免了使用反射时出现的性能成本和编译时可验证性.
public delegate T FromBytesFunc<T>(byte[] bytes, ref int index);
public static List<T> FromBytes<T>(byte[] bytes, ref int index,
FromBytesFunc<T> function)
{
var count = bytes[index++];
var listOfFoo = new List<T>();
for (var i = 0; i < count; i++)
{
listOfFoo.Add(function(bytes, ref index));
}
return listOfFoo;
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您创建方法而不是它所使用的类,那么您可以让编译器推断泛型参数.它可以像这样调用:
var list = SomeClass.FromBytes(bytes, ref index, Foo1.FromBytes);
Run Code Online (Sandbox Code Playgroud)
这将是所有未来观众的摘要。
由于您不能只调用该方法,因此主要问题是获取委托。有两种方法:
您可能认为反射很慢,但性能不是问题。如果委托存储在静态字段中,则每个类只需执行一次,因为泛型类型不共享静态成员。
编译时可验证性是一个问题。如果您非常关心编译时可验证性,您应该从调用者传递委托。如果您更关心干净的方法调用,则必须牺牲编译时可验证性。
PS:有些人建议使用字典或 switch/case 或 if/else 来存储代表。这是你不应该做的事情。这与将委托存储在泛型类的静态字段中没有任何优势(泛型类型不共享静态成员)。
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |