[英].Net Reflection calling a function with a generic parameter - How to pass the type to the function
[英]How to pass a type parameter of a generic function from string value?
有一个通用函数
Result<T> F<T>(int id) { .... }
void F2<T>(Result<T> r) { ... }
并且有一个字符串列表(从appsettings.json
读取)。
List<(string, int)> s = new List<(string, int)> {
("int", 10),
("string", 21),
("DateTime", 31),
("int", 20)
... }
如何使用字符串列表中的项目调用F
?
foreach (var (t, id) in s)
{
var result = F<???>(id); // need the type from t here
F2<???>(result);
}
为什么我问这个:
原始代码有一个列表
F<int>(123);
F<string>(345);
F<int>(32);
F<Othertype>(32);
... many more ...
在源代码中。 它需要不时更新/添加。 我正在尝试将它移动到配置文件中,这样我就不需要每次都修改代码并重新编译代码。
简短的回答是F<???>
是不可能的。 所有这些都发生在编译时。 最接近的情况是使用“动态”,但是,您遇到了同样的问题。 您无法直接访问“类型元素”,只能通过反射访问。
var type = Type.GetType("System.Int32");
var obj = Activator.CreateInstance(typeof(F<>).MakeGenericType(type));
如您所见,您必须将类型存储为带有名称空间的全名,但这是方法。
另一种方法是使用Dictionary<string, F<T>>
但这会强制您在每次添加要管理的新类型时更新地图。 (如果您使用Dictionary<string, Type>
您会遇到与第一个选项相同的问题)。
你必须考虑到如果你想调用方法、属性和一切你必须用反射来做
编辑:OTP 解决方案是动态编写代码,编译它并在运行时加载它(不要这样做)
这让我想到了一个问题,你想做什么? 这听起来像是对一个简单问题的过度考虑。
我会创建一个字典来从string
映射到Type
;
var mappings = new Dictionary<string,Type>(){ { "int", typeof(int) }, ... };
然后我会修改您的F<T>()
以便您可以轻松调用非通用版本;
public static void F<T>(int value) => F(typeof(T), value);
public static void F(Type type, int value){
...
}
剩下的现在应该很明显了;
Dictionary<string, int> config = ...
foreach (var t in config)
{
F(mappings[t.Key], t.Value);
}
void F<T>(int id) { .... }
void F(string typeName , int id)
{
if ( typeName == "int" )
{
F<Int>(id)
}else if ( typeName == "string")
{
F<string>(id)
}
//... all type
}
foreach (string t in s)
{
F(t,val);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.