从泛型方法获取值而不提供类型

本文关键字:类型 泛型方法 获取 | 更新日期: 2023-09-27 18:18:41

我试图创建一个类,其中一个属性是通用的,没有类本身是通用的。我发现你做不到;不允许使用通用属性。我在这里挖了一下,我找到了一个通用的属性,我找到了一个工作,很好地为我工作。

随后,我结束了这门课…

[Serializable]
public class ConfigurationItem
{
    private readonly Type type;
    public string Description { get; set; }
    public IDictionary<string, ConfigurationItem> Items { get; private set; }
    public string Name { get; set; }
    public string Summary { get; set; }
    public object Value { get; private set; }
    public ConfigurationItem(string name, Type type = null, object value = null)
    {
        this.Name = name;
        this.type = type ?? typeof(string);
        this.Value = value;
        Items = new Dictionary<string, ConfigurationItem>();
    }
    public string Export()
    {
        return JsonConvert.SerializeObject(this);
    }
    public T GetValue<T>()
    {
        return (T)Convert.ChangeType(Value, type);
    }
}

现在我唯一的问题是,如果我想获得值,正确转换,我必须在调用GetValue()时提供类型。本能地,我不禁觉得,既然类知道应该返回的类型,那么我应该可以构造一个不需要我提供任何额外信息的GetValue()方法。

我想不出是怎么回事。

我确实发现线程得到一个通用的方法来推断类型参数从运行时类型,这似乎表明这是可能的,但我了解很少关于反射,不能使任何意义所说的

是否有一种方法构建一个GetType()方法,不需要我提供泛型类型?你能用我那弱智的大脑能理解的方式解释一下吗?

编辑许多人实际上已经指出,我真的不需要这样做,尽管如此,作为一个学习练习,我遵循了@ShoaibShakeel的建议,看看c# dynamic类型,并提出了这些额外的方法…

    public dynamic GetValue()
    {
        return typeof(ConfigurationItem)
            .GetMethod("GetReturnValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
            .MakeGenericMethod(type)
            .Invoke(this, new object[] { });
    }
    private T GetReturnValue<T>()
    {
        return (T)Convert.ChangeType(Value, type);
    }

从泛型方法获取值而不提供类型

我本能地觉得,既然类知道应该返回的类型

虽然Value对象确实知道它自己的类型,但是这个信息只在运行时可用(一旦有一个具有类型的实际对象)。因此,为了在编译时获得类型信息,您需要提供必要的信息。毕竟,不可能静态地知道那里赋值了什么对象。

但是假设GetValue()能够自动返回类型的对象,您想用它做什么?
var x = configurationItem.GetValue();

那么x应该是什么类型,之后你想用它做什么?你只想打印出来还是怎么的?那么object就足够了。你想用它计算什么吗?然后,您可能已经要求它是intfloat或其他类型,因此您将需要一个实际的静态类型-这就是为什么您必须提供该类型信息。

仅仅因为返回类型是object,并不意味着对象本身丢失了类型信息。分配给object属性的字符串仍然是字符串,即使您在很久以后检索它。如果你希望得到一个字符串,并且想对它做些什么,那么你当然可以把它强制转换成一个字符串。

No.

编译器不能从它所赋值的变量推断类型,因为它是二义性的,特别是在大型继承树中。

考虑

一行
object o = configurationItem.GetValue<int>();

int可能是您的值的有效转换,但object不是,因为object不实现IConvertible接口(Convert.ChangeType()所要求的)。

我能够让我的类返回一个值,正确转换,使用反射和动态使用以下添加到我的原始类。

public dynamic GetValue()
{
    return typeof(ConfigurationItem)
        .GetMethod("GetReturnValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
        .MakeGenericMethod(type)
        .Invoke(this, new object[] { });
}
private T GetReturnValue<T>()
{
    return (T)Convert.ChangeType(Value, type);
}