繁体   English   中英

如何从字符串值传递泛型函数的类型参数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM