如何将对象转换为 C# 中具有泛型类型的类?

问题描述 投票:0回答:1

正在努力解决这个问题。我有一堂课看起来像这样。

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# casting
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.