C# 如何从字符串值传递泛型函数的类型参数?
有一个泛型函数C# 如何从字符串值传递泛型函数的类型参数?,c#,C#,有一个泛型函数 Result<T> F<T>(int id) { .... } void F2<T>(Result<T> r) { ... } 如何使用字符串列表中的项目调用F foreach (var (t, id) in s) { var result = F<???>(id); // need the type from t here F2<???>(result); } foreach(s中的变量
Result<T> F<T>(int id) { .... }
void F2<T>(Result<T> r) { ... }
如何使用字符串列表中的项目调用F
foreach (var (t, id) in s)
{
var result = F<???>(id); // need the type from t here
F2<???>(result);
}
foreach(s中的变量(t,id))
{
var result=F(id);//此处需要t的类型
F2(结果);
}
我为什么问这个: 原始代码有一个
F<int>(123);
F<string>(345);
F<int>(32);
F<Othertype>(32);
... many more ...
F(123);
F(345);
F(32);
F(32);
... 还有很多。。。
在源代码中。它需要不时更新/添加。我正在尝试将其移动到配置文件中,这样我就不需要每次修改代码并重新编译代码。我将创建一个字典,以便从
字符串映射到类型
var mappings=newdictionary(){{“int”,typeof(int)},…};
然后我会修改您的F()
,这样您就可以轻松调用非泛型版本
publicstaticvoidf(int值)=>F(typeof(T),value);
公共静态void F(类型,int值){
...
}
剩下的应该是显而易见的
字典配置=。。。
foreach(配置中的变量t)
{
F(映射[t.Key],t.Value);
}
我会创建一个字典,将字符串
映射到类型
var mappings=newdictionary(){{“int”,typeof(int)},…};
然后我会修改您的F()
,这样您就可以轻松调用非泛型版本
publicstaticvoidf(int值)=>F(typeof(T),value);
公共静态void F(类型,int值){
...
}
剩下的应该是显而易见的
字典配置=。。。
foreach(配置中的变量t)
{
F(映射[t.Key],t.Value);
}
void F(int-id){..}
void F(字符串类型名,int-id)
{
if(typeName==“int”)
{
F(id)
}else if(typeName==“string”)
{
F(id)
}
//…所有类型
}
foreach(s中的字符串t)
{
F(t,val);
}
void F(int-id){..}
void F(字符串类型名,int-id)
{
if(typeName==“int”)
{
F(id)
}else if(typeName==“string”)
{
F(id)
}
//…所有类型
}
foreach(s中的字符串t)
{
F(t,val);
}
简短的回答是F
不可能。所有这些都发生在编译时。最接近的情况是使用“动态”,但您也有同样的问题。您不能直接访问“类型元素”,只能通过反射
var type = Type.GetType("System.Int32");
var obj = Activator.CreateInstance(typeof(F<>).MakeGenericType(type));
var type=type.GetType(“System.Int32”);
var obj=Activator.CreateInstance(typeof(F).MakeGenericType(type));
如您所见,必须将类型存储为带有名称空间的全名,但这是一种方法
另一种方法是使用字典
,但这会迫使您在每次添加要管理的新类型时更新映射。(如果使用字典
,则与第一个选项的问题相同)
您必须考虑到,如果您想要调用方法、属性以及所有您必须使用反射来完成的事情
编辑:OTP解决方案是动态编写代码,编译并在运行时加载(不要这样做)
这让我想到一个问题,你想做什么?这听起来像是对一个简单问题的过度思考。简单的答案是F
不可能。所有这些都发生在编译时。最接近的情况是使用“动态”,但您也有同样的问题。您不能直接访问“类型元素”,只能通过反射
var type = Type.GetType("System.Int32");
var obj = Activator.CreateInstance(typeof(F<>).MakeGenericType(type));
var type=type.GetType(“System.Int32”);
var obj=Activator.CreateInstance(typeof(F).MakeGenericType(type));
如您所见,必须将类型存储为带有名称空间的全名,但这是一种方法
另一种方法是使用字典
,但这会迫使您在每次添加要管理的新类型时更新映射。(如果使用字典
,则与第一个选项的问题相同)
您必须考虑到,如果您想要调用方法、属性以及所有您必须使用反射来完成的事情
编辑:OTP解决方案是动态编写代码,编译并在运行时加载(不要这样做)
这让我想到一个问题,你想做什么?这听起来像是对一个简单问题的过度思考。为什么不使用type参数来定义要输入的参数的类型void F(IEnumerable items){access items here}
既然您不能这样做(必须将其转换为类型并使用反射),我可以问一下您的最终目标是什么吗?F
做什么?如果您可以从实际类型(而不是int
/string
)开始,并希望看到非常数据控制的解决方案,那么最后应该给您提供操作
。。。可能按照所有答案的建议放入字典。为什么不使用type参数定义要输入的参数的类型void F(IEnumerable items){access items here}
既然您不能这样做(必须将其转换为类型并使用反射),我可以问一下您的最终目标是什么吗?F
做什么?如果您可以从实际类型(而不是int
/string
)开始,并希望看到非常数据控制的解决方案,那么最后应该给您提供操作
。。。可能按照所有答案的建议放入字典。我正在改进一个遗留程序,该程序处理问题中的异类数据类型-T
。@ca9163d9如果不阅读实例化代码和用法,我将帮不了你更多忙。但唯一的选择(我记得)是我指出的。我正在改进一个遗留程序,该程序处理问题中的异构数据类型-T
。@ca9163d9如果不阅读实例化的代码和用法,我将帮不上什么忙。但唯一的选择(我记得)是我指出的。
var type = Type.GetType("System.Int32");
var obj = Activator.CreateInstance(typeof(F<>).MakeGenericType(type));