好的,我有一个通用类。基础是这样的:
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 '”。
所以希望有一个明智的人可以帮助我解决这个问题。
答案 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
仅需要一个编译时间名称,其中包含类型参数。