比较类型,如果一个可以为空

时间:2017-06-01 08:47:06

标签: c# reflection types nullable

我需要检查两种类型是否相同:

private bool AreOfTheSameType(object obj1, object obj2) {
  return obj1.GetType()==obj2.GetType();
}

这适用于这个值:

var test1=AreOfTheSameType(new DateTime(), new DateTime()) // true;
var test2=AreOfTheSameType(new int(), new DateTime()) // false;

我现在想要的是,以下内容也会返回true:

var test3=AreOfTheSameType(new int?(), new int()) 

因此,如果类型具有相同的基础,但是一个可以为空,另一个不是,我也想将其返回为真。或者以另一种方式说我希望有一个函数返回我是否可以直接使用反射将obj1存储到obj2而不必转换值。

更新

我减少了代码以使其更具可读性。看起来这次是反作用的。现实世界的代码如下:

var entity = Activator.CreateInstance(typeof(T));
Type entityType = typeof(T);
PropertyInfo[] entityProperties = entityType.GetProperties();
foreach (KeyValuePair<string, object> fieldValue in item.FieldValues)
{
   if (fieldValue.Value == null) continue;
   var property = entityProperties.FirstOrDefault(prop => prop.Name == fieldValue.Key);
   if (property != null && property.CanWrite)
   {
      Type valueType = fieldValue.Value.GetType();
      if (fieldValue.Value.GetType() == property.PropertyType) {
        // Assign
      }
   }
}

&#34; //分配&#34;上的问题 - 行是,我有以下两种类型:

fieldValue.Value.GetType().ToString()="System.DateTime"
property.PropertyType.ToString()="System.Nullable`1[System.DateTime]"

这些内容不同但可以分配

3 个答案:

答案 0 :(得分:3)

  

这些内容不同但可以分配

看起来像是Type.IsAssignableFrom方法之后:

var dt = typeof(DateTime);            
var nd = typeof(DateTime?);

Console.WriteLine(dt.IsAssignableFrom(nd)); // false
Console.WriteLine(nd.IsAssignableFrom(dt)); //true

实例:http://rextester.com/KDOW15238

答案 1 :(得分:2)

在可空类型上调用GetType会返回原始类型:

int? i = 5;  
Type t = i.GetType();  
Console.WriteLine(t.FullName); //"System.Int32"  

因此AreOfTheSameType((int?)5, 5)应该返回true

但是只要您点击Nullable<T>,就会获得null(如果Nullable<T>.HasValuefalse),或者您获得了盒装基础值,则会失去“可空的“部分。因此,您在此处遇到的问题是,new int?在传递给方法时会被装入null对象。

答案 2 :(得分:2)

可空类型的问题是空值框为null,一旦它们为null,您就无法找出它们是什么。那么解决这个问题的唯一方法就是使用泛型:

private bool AreOfTheSameType<T1,T2>(T1 obj1, T2 obj2) {
  // get the types as best we can determine
  var t1 = obj1?.GetType() ?? typeof(T1);
  var t2 = obj2?.GetType() ?? typeof(T2);

  // Nullable<T> => T
  t1 = Nullable.GetUnderlyingType(t1) ?? t1;
  t2 = Nullable.GetUnderlyingType(t2) ?? t2;

  // compare
  return t1 == t2;
}

这将使用对象如果可用(允许子类等),但如果对象为null则将回退到typeof - 这意味着它应该适用于{{1等等... 只要传入的表达式的类型不是int?开头的;如果它 object并且值为object,那么......你运气不好 - 你无法找到原始类型。我的意思是:

这应该没问题:

null

但这会失败:

var test3=AreOfTheSameType(new int?(), new int());