首页 新闻 会员 周边

c# 使用 反射 判断 属性 的值 是否为 该属性 所属类型 的 默认值

1
悬赏园豆:50 [已关闭问题] 解决于 2013-08-29 08:35

先说一下问题来由:

调用他人的代码,根据查询条件返回类实例。蛋疼的是当不存在符合条件的实例时,他没有返回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,不能直接比较。

现在的问题集中在如何得知反射出来的属性值,是该属性类型的默认值。不知各位高人有没有什么指教。

pfdcnblogs的主页 pfdcnblogs | 初学一级 | 园豆:172
提问于:2013-08-28 16:27
< >
分享
其他回答(1)
0

对方空的时候 返回的既然是新的对象,你就直接看对象是否有值就行了,他只是不为null,其实里面是空的,使用List赋值,没值count是空的

风醉 | 园豆:1197 (小虾三级) | 2013-08-28 17:18

对方返回的不是ClassA的集合,而是ClassA的一个实例。不能用集合长度判断的。

支持(0) 反对(0) pfdcnblogs | 园豆:172 (初学一级) | 2013-08-28 17:25

@pfdcnblogs: 实例更会有默认值啊,比如int 默认为0 而你的实际值不会为0

支持(0) 反对(0) 风醉 | 园豆:1197 (小虾三级) | 2013-08-28 18:45
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;
    }
yourebi | 园豆:184 (初学一级) | 2019-10-19 16:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册