正在努力解决这个问题。我有一堂课看起来像这样。
public class Result<T> where T: class, new()
{
public T? Value { get; set; }
}
我现在尝试将一个对象转换为此类,但我不确定如何处理通用部分。
object? funcValue = await GetResponse().Value;
// if (funcValue is Result<object> response) // this doesn't work
if (funcValue.GetType().Name.StartsWith("Result")) // The actual name is Result`1 when debugging
{
var response = (Result<object>) value; // code explodes here but I don't know the generic type to do a proper cast
var res = response.Value; // trying to access the generic type from the Result class.
}
C# 是一种静态类型语言。要在运行时获取泛型类型,您必须在编译时知道它。您唯一能做的就是使用反射来调用可以使用您的类型的泛型方法。
执行诸如
funcValue.GetType().Name.StartsWith("Result")
之类的操作来确定您的类型是否为 Result<>
并不是最好的方法。
这就是有效的:
object? funcValue = (await GetResponse()).Value;
var type = funcValue.GetType();
if (type.IsGenericType)
{
var gtype = type.GetGenericTypeDefinition();
if (gtype.Equals(typeof(Result<>)))
{
var ttype = type.GenericTypeArguments.First();
/* do stuff here with the run-time type of `T` in `Result<T>` */
}
}
现在,为了做一些有意义的事情,我将这段代码放在一起:
private Dictionary<Type, Delegate> _registry = new();
public class Response
{
public object Value;
}
Task<Response> GetResponse() => Task.Run(() => new Response() { Value = new Result<Foo>() { Value = new Foo() } });
public class Result<T> where T : class, new()
{
public T? Value { get; set; }
}
public class Foo { }
字典允许我注册我想要做的事情的类型。因此,例如:
_registry[typeof(Foo)] =
(Action<Result<Foo>>)(rf
=> Console.WriteLine($"I have a Result<Foo>: {rf?.Value?.GetType()}"));
现在,我可以这样写:
object? funcValue = (await GetResponse()).Value;
var type = funcValue.GetType();
if (type.IsGenericType)
{
var gtype = type.GetGenericTypeDefinition();
if (gtype.Equals(typeof(Result<>)))
{
var ttype = type.GenericTypeArguments.First();
_registry[ttype].DynamicInvoke(funcValue);
}
}
当我将所有这些放在一起并运行它时,我得到了这个:
I have a Result<Foo>: Foo