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));