对象初始值设定项内的属性可以互相引用吗?
在动态对象创建匿名类型对象(即在对象初始化程序内)期间,属性是否可能以某种方式相互引用? 下面的简化示例需要重用Age
属性,而不需要对GetAgeFromSomewhere()
进行第二次大量调用。 当然它不起作用。 有关如何实现这一目标的任何建议?
var profile = new { Age = GetAgeFromSomewhere(id), IsLegal = (Age>18) };
对于动态对象匿名类型的对象初始化器,这样的事情是可能的还是不可能的 ?
不幸的是,即使使用显式类型的对象,它也是不可能的。 这是因为对象初始化器的工作方式。 例如:
public class MyClass { public int Age = 10; public bool IsLegal = Age > 18; }
在“IsLegal”处产生此编译器错误:
错误1字段初始值设定项无法引用非静态字段,方法或属性“MyClass.Age”…
字段初始值设定项不能引用其他非静态字段,并且由于匿名类型不创建静态字段,因此不能使用一个字段的值来初始化另一个字段。 解决这个问题的唯一方法是声明匿名类型之外的变量并在初始化程序中使用它们。
int age = GetAgeFromSomewhere(id); var profile = new { Age = age, IsLegal = age > 18 };
不要复杂化,保持简单
//Create a variable var age = GetAgeFromSomewhere(id); var profile = new { Age = age, IsLegal = age>18 }
在对象初始化器中无法实现所需的function。 您无法读取正在初始化的对象的属性。 (无论这种类型是匿名的还是无关紧要。)
相反,创建一个类
public class Profile { public Profile(int id) { Age = GetAgeFromSomewhere(id); } public int Age { get; private set; } public int IsLegal { get { return Age > 18; } } }
或者把时代变成懒惰的方式:
public class Profile { private readonly int _id; public Profile(int id) { _id = id; } private int? _age; public int Age { get { if (_age == null) { _age = GetAgeFromSomewhere(_id); } return _age.Value; } } public int IsLegal { get { return Age > 18; } } }
或使用Lazy
类(从Framework 4.0开始):
public class Profile { public Profile(int id) { // C# captures the `id` in a closure. _lazyAge = new Lazy( () => GetAgeFromSomewhere(id) ); } private Lazy _lazyAge; public int Age { get { return _lazyAge.Value; } } public int IsLegal { get { return Age > 18; } } }
像这样称呼它
var profile = new Profile(id);