先说一下问题来由:
调用他人的代码,根据查询条件返回类实例。蛋疼的是当不存在符合条件的实例时,他没有返回null,而是new了一个新实例。
搞得我在检查返回数据时,不仅要检查返回值是否为null,还要检查返回值的某个属性(作为标识)是否为默认值,才能确认到底有没有数据返回。
1 //有一个类 2 public class ClassA 3 { 4 public string id {get;set;} //guid类型 5 public int num {get;set;} 6 public object other {get;set;} 7 } 8 9 //我这样调用 10 ClassA A = (他人代码返回); 11 if(A != null && A.id.IsNotNullAndEmpty() 12 && !string.Equals( A.id, Guid.Empty.ToString(), StringComparison.OrdinalIgnoreCase)) 13 { 14 //有数据返回 15 }
我希望能有一个通用方法,使用泛型,判断返回的类型实例是否为null或默认值。
1 public static bool IsNotNullAndDefaultPK<T>(Expression<Action<T>> lamda, T entity) where T:class 2 { 3 #region//检查实例是否为null 4 if (entity == null) 5 { 6 return false; 7 } 8 #endregion 9 10 #region//获取主键的名 11 string key = string.Empty; 12 string call = lamda.Body.ToString(); //X.Id 13 Regex reg = new Regex(@"[\.][\w][\w\s]*?[^\(]"); //惰性匹配“.Id” 14 Match match = reg.Match(call); 15 if (match.Success) 16 { 17 //移除分隔标识和首位空白 18 key = match.Value.Trim(new char[] { '.'}).Trim(); //Id 19 } 20 #endregion 21 22 #region//获取主键的值 23 object value = null; 24 Type valueType = null; 25 Type entityType = typeof(T); 26 PropertyInfo pi = entityType.GetProperty(key, BindingFlags.Public); 27 if (pi != null) 28 { 29 value = pi.GetValue(entity, null); 30 valueType = pi.PropertyType; 31 } 32 #endregion 33 34 #region//检查主键的值是否为默认值 35 36 #region//属性为string类型 37 if (valueType == typeof(string)) 38 { 39 //检查主键的值是否为null 40 if (value == null) 41 { 42 return false; 43 } 44 else 45 { 46 //检查主键的值是否为空白值或默认GUID值 47 string temp = value.ToString(); 48 if (temp.IsNullOrEmpty() 49 || string.Equals(temp, default(Guid).ToString(), StringComparison.OrdinalIgnoreCase)) 50 { 51 return false; 52 } 53 else 54 { 55 return true; 56 } 57 } 58 } 59 #endregion 60 61 #region//属性为引用类型 62 if (!valueType.IsValueType) 63 { 64 //检查主键的值是否为null 65 if (value == null) 66 { 67 return false; 68 } 69 else 70 { 71 return true; 72 } 73 } 74 #endregion 75 76 #region//属性为值类型 77 if (valueType.IsValueType) 78 { 79 //检查主键的值是否为null 80 if (value == null) 81 { 82 return false; 83 } 84 else 85 { 86 //对值类型进行分别判断 87 return true; 88 } 89 } 90 #endregion 91 92 #endregion 93 94 return false; 95 }
可以看出,还没写完,就已经很长了。甚是不爽,就想能不能直接根据Type得到该类型的默认值。
经过查找,在这里(http://bytes.com/topic/c-sharp/answers/736355-default-value-any-type)找到了类似的需求,但使用Activator.CreateInstance(type)返回的值是经过装箱的object,不能直接比较。
现在的问题集中在如何得知反射出来的属性值,是该属性类型的默认值。不知各位高人有没有什么指教。
对方空的时候 返回的既然是新的对象,你就直接看对象是否有值就行了,他只是不为null,其实里面是空的,使用List赋值,没值count是空的
对方返回的不是ClassA的集合,而是ClassA的一个实例。不能用集合长度判断的。
@pfdcnblogs: 实例更会有默认值啊,比如int 默认为0 而你的实际值不会为0
public static bool IsNullOrDefault<T>(T argument)
{
// deal with normal scenarios
if (argument == null) return true;
if (object.Equals(argument, default(T))) return true;
// deal with non-null nullables
Type methodType = typeof(T);
if (Nullable.GetUnderlyingType(methodType) != null) return false;
// deal with boxed value types
Type argumentType = argument.GetType();
if (argumentType.IsValueType && argumentType != methodType)
{
object obj = Activator.CreateInstance(argument.GetType());
return obj.Equals(argument);
}
return false;
}