gpt4 book ai didi

c# - 如何在不知道类型的情况下转换泛型类型

转载 作者:行者123 更新时间:2023-11-30 12:28:55 25 4
gpt4 key购买 nike

我正在尝试在运行时创建一个通用对象。到目前为止,我已经能够创建它,但我无法弄清楚如何施放它。我拥有的是枚举对象,我想生成将枚举值转换为自定义字符串以映射到遗留数据库的 EnumMapper。

Type enumType = myEnum.GetType();
Type enumMapperType = typeof(EnumMapper<>)
.GetGenericTypeDefinition().MakeGenericType(enumType);
var mapper = Activator.CreateInstance(enumMapperType); // OK
EnumMapper<> mapper = (EnumMapper<>) Activator.CreateInstance(enumMapperType); // Error

当我在调试器中检查对象时,它已按预期创建,但我如何转换它才能使用它?

类(class):

public class EnumMapper<T> : IEnumMapper<T>

界面:

public interface IEnumMapper<T>
{
T EnumValue(string value);

bool HasEnumValue(string stringValue);

bool HasStringValue(T enumValue);

string StringValue(T enumValue);
}

Error   2   ; expected  \EnumMapperTest.cs  36
Error 4 ; expected \EnumMapperTest.cs 36
Error 1 Invalid expression term '>' \EnumMapperTest.cs 36
Error 3 Invalid expression term '>' \EnumMapperTest.cs 36
Error 34 Only assignment, call, increment, decrement, and new object expressions can be used as a statement \EnumMapperTest.cs 36
Error 36 The name 'mapper' does not exist in the current context \EnumMapperTest.cs 36
Error 35 Using the generic type 'EnumMapper<T>' requires 1 type arguments \EnumMapperTest.cs 36
Error 37 Using the generic type 'EnumMapper<T>' requires 1 type arguments \EnumMapperTest.cs 36

最佳答案

据我所知,您需要的确切内容在 C# 中是不可能的。基本上,您需要一个方法具有不同的类型或返回的变量,基于常规的非通用参数的值,即如果参数是 typeof(Enum1) , 结果变量是 EnumMapper<Enum1>如果参数是 typeof(Enum2) , 结果变量是 EnumMapper<Enum2> .

您可以使用泛型参数来做到这一点,但是,由于泛型都是关于编译时信息的,而您只有运行时的值,因此在这种情况下不能使用它们。

你能做的(也是我已经做的)是使用动态代码来解决这个问题,小心尽快进入静态类型的土地(动态真的很有感染力,有人笑着说,有人说像病毒):

public dynamic GetMapperObject(Type enumType)
{
Type enumMapperType = typeof(EnumMapper<>)
.GetGenericTypeDefinition()
.MakeGenericType(enumType);
var mapper = Activator.CreateInstance(enumMapperType);
return mapper;
}

调用代码如下:

var mapper = GetMapperObject(enumType);
//dynamic call, bind the resut to a statically typed variable
bool result = mapper.HasEnumValue("SomeStringValue")

(旧答案,只是为问题添加了另一个间接级别:))

您可以将所有这些包装在一个通用方法中,如下所示:

public EnumMapper<T> GetMapperObject<T>()
{
Type enumType = typeof(T);
Type enumMapperType = typeof(EnumMapper<>)
.GetGenericTypeDefinition()
.MakeGenericType(enumType);
var mapper = Activator.CreateInstance(enumMapperType);
return mapper as EnumMapper<T>;
}

并调用它

var mapper = GetMapperObject<EnumMapperTestEnum>();

但是,如果枚举只有一个值,则可以使用类型推断,例如:

//everything is the same, just different signature
public EnumMapper<T> GetMapperByExample<T>(T item)
{
Type enumType = typeof(T);
Type enumMapperType = typeof(EnumMapper<>)
.GetGenericTypeDefinition()
.MakeGenericType(enumType);
var mapper = Activator.CreateInstance(enumMapperType); // OK
return mapper as EnumMapper<T>;
}

并用类型推断调用它

var mapper = GetMapperByExample(EnumMapperTestEnum.SomeValue); 

关于c# - 如何在不知道类型的情况下转换泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20186391/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com