这个对象能够告诉它有多少属性不是 null/whitespace/empty 有什么问题?
What is wrong with this object being capable of telling how many of its properties are not null/whitespace/empty?
我想弄清楚为什么以下代码会抛出 WhosebugException(我终于在 SO 中发布了 WhosebugException!)。
调试似乎指出 p.GetValue(this) 正在生成更多调用。
实际上是什么触发了无限调用链?是因为 p.GetValue(this) 最终 returns 当前对象的一个实例,因此就像构造一个新实例一样(并且在其构造中构造自身的每个对象都会导致 Whosebug 异常)?
我对以下代码的意图是让一个对象能够告诉它有多少属性具有 null/space/empty 值。
public class A
{
public string S1 { get; set; }
public string S2 { get; set; }
public int NonInitializedFields
{
get
{
int nonNullFields = 0;
var properties = this.GetType().GetProperties();
foreach (var p in properties)
{
var value = p.GetValue(this);
if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
nonNullFields++;
}
return nonNullFields;
}
}
}
//the following throws a WhosebugException (the construction line itself)
A a1 = new A1{ S1 = "aaa"};
Console.WriteLine(a1.NonInitializedFields);
P.S。我的想法本来只涉及简单的字符串属性,没有别的,所以这种方法与其他类型可能出现的问题无关。
您有一个 属性,当您执行 "get" 访问器时,它会找到所有 属性 并获取它们的值。所以它会递归地执行自己。
如果您只需要字符串属性,您应该在 获取值之前检查 属性 类型 :
var properties = GetType().GetProperties().Where(p => p.PropertyType == typeof(string));
此时,由于您的NonInitializedFields
属性 没有return 类型的string
,它不会被执行。
请注意,就我个人而言,无论如何,我会将其设为方法调用而不是 属性。这也可以解决问题,因为该方法在查找属性时不会找到自己。
我也将其重命名为:
- A 属性 不一定由字段支持
- 字段可以显式初始化为
null
或对仅包含空格的字符串的引用
IMO,一种叫做 GetNonWhitespaceStringPropertyCount()
的方法会更准确。您还可以使整个实现成为 LINQ 查询:
return GetType().GetProperties()
.Where(p => p.PropertyType == typeof(string))
.Select(p => p.GetValue(this))
.Count(v => !string.IsNullOrWhitespace((string) v));
请注意,我已经解决了您代码中的下一个问题 - 您本应计算 non-null/empty 个值,但实际上您计算的是 null/empty个。
我想弄清楚为什么以下代码会抛出 WhosebugException(我终于在 SO 中发布了 WhosebugException!)。
调试似乎指出 p.GetValue(this) 正在生成更多调用。
实际上是什么触发了无限调用链?是因为 p.GetValue(this) 最终 returns 当前对象的一个实例,因此就像构造一个新实例一样(并且在其构造中构造自身的每个对象都会导致 Whosebug 异常)?
我对以下代码的意图是让一个对象能够告诉它有多少属性具有 null/space/empty 值。
public class A
{
public string S1 { get; set; }
public string S2 { get; set; }
public int NonInitializedFields
{
get
{
int nonNullFields = 0;
var properties = this.GetType().GetProperties();
foreach (var p in properties)
{
var value = p.GetValue(this);
if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
nonNullFields++;
}
return nonNullFields;
}
}
}
//the following throws a WhosebugException (the construction line itself)
A a1 = new A1{ S1 = "aaa"};
Console.WriteLine(a1.NonInitializedFields);
P.S。我的想法本来只涉及简单的字符串属性,没有别的,所以这种方法与其他类型可能出现的问题无关。
您有一个 属性,当您执行 "get" 访问器时,它会找到所有 属性 并获取它们的值。所以它会递归地执行自己。
如果您只需要字符串属性,您应该在 获取值之前检查 属性 类型 :
var properties = GetType().GetProperties().Where(p => p.PropertyType == typeof(string));
此时,由于您的NonInitializedFields
属性 没有return 类型的string
,它不会被执行。
请注意,就我个人而言,无论如何,我会将其设为方法调用而不是 属性。这也可以解决问题,因为该方法在查找属性时不会找到自己。
我也将其重命名为:
- A 属性 不一定由字段支持
- 字段可以显式初始化为
null
或对仅包含空格的字符串的引用
IMO,一种叫做 GetNonWhitespaceStringPropertyCount()
的方法会更准确。您还可以使整个实现成为 LINQ 查询:
return GetType().GetProperties()
.Where(p => p.PropertyType == typeof(string))
.Select(p => p.GetValue(this))
.Count(v => !string.IsNullOrWhitespace((string) v));
请注意,我已经解决了您代码中的下一个问题 - 您本应计算 non-null/empty 个值,但实际上您计算的是 null/empty个。