在通用类中初始化通用参数

时间:2018-10-11 12:30:58

标签: c# generics

好的,我有一个通用类。基础是这样的:

public class GenericPrimitiveContainer<T> : IGetAndSetGenericValue
{
    private T _value;

    public T Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value;
        }
    }
}

足够好。我在该类中也有一个SetValue方法,该方法接受一个对象并将其设置为使用此代码的值:

PropertyInfo pi = this.GetType().GetProperty("Value");
            pi.SetValue(this, o, null);

这还不是全部,因为它还会检查对象的类型和Value的类型并进行比较。如果它们相同,则将o(对象)分配给Value。如果它们不相同,则将应用转换。我不会去讨论这个问题,因为那不是问题所在(我确定是著名的遗言)。

问题在于Value是否为字符串类型。如前所述,我比较类型以查看它们是否相同。如下所示(“ o”是传入的对象):

Type t1 = Value.GetType();
        Type t2 = o.GetType();
        if (t1 == t2) ...

如果T为int,则没有问题。如果T为字符串,则“值”仅为“空”。我什至无法查看它是否为字符串,因为它只是null。

作为测试,我尝试了摆脱检查并在我知道将字符串传递给该方法的情况下测试set方法的方法。最初,Value仍然为空,但可以正常工作,并且已分配Value。

现在,我知道字符串不是原始类型,因此与int的工作方式略有不同,但是我不确定如何解决此问题。我考虑过将_value初始化为default(T),但这没有用。我还向该类添加了一个构造函数,该构造函数执行相同的操作。那也不起作用。

我也曾尝试用'where t:new()'约束该类,但这是行不通的,因为String不是“具有公共无参数构造函数的非抽象类型,以便将其用作参数'T '”。

所以希望有一个明智的人可以帮助我解决这个问题。

1 个答案:

答案 0 :(得分:4)

您的问题是Value.GetType()不能满足您的要求。这是一个非常简短的完整示例:

using System;

    static class Generic
    {
        public static string WhatIsT<T>(T value)
        {
            return $"T is {value.GetType().FullName}";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int i = 5;
            Console.WriteLine(Generic.WhatIsT(i));

            string s = "hello";
            Console.WriteLine(Generic.WhatIsT(s));

            s = null;
            Console.WriteLine(Generic.WhatIsT(s));

            Console.ReadLine();
        }
    }

WhatIsT的第一次和第二次调用都可以,但是在第三次调用上将有一个空引用异常。

如果您确实真的真的需要知道泛型的确切名称,那么您已经被关闭了-注意注释中的警告,这几乎肯定是不正确的要做的事情-只需使用typeof(T),就像这样:

            return $"T is {typeof(T).FullName}";

结果:

T is System.Int32
T is System.String
T is System.String

请记住,GetType需要一个对象。 typeof仅需要一个编译时间名称,其中包含类型参数。