在创建动态对象一个匿名类型的对象(即在对象初始化程序内)时,属性是否可能以某种方式相互引用?我在下面的简化示例需要重用Age
属性,而不需要对GetAgeFromSomewhere()
进行第二次大量调用。当然它不起作用。有关如何实现这一目标的任何建议吗?
var profile = new {
Age = GetAgeFromSomewhere(id),
IsLegal = (Age>18)
};
使用动态对象匿名类型对象初始值设定项可能或不可能这样吗?
答案 0 :(得分:10)
不幸的是,即使使用显式类型的对象,它也是不可能的。这是因为对象初始化器的工作方式。例如:
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
};
答案 1 :(得分:5)
不要让事情复杂化,保持简单
//Create a variable
var age = GetAgeFromSomewhere(id);
var profile = new {
Age = age,
IsLegal = age>18
}
答案 2 :(得分:3)
在对象初始化器中无法实现所需的功能。您无法读取正在初始化的对象的属性。 (无论这种类型是匿名的还是无关紧要。)
相反,创建一个类
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<T>
类(从Framework 4.0开始):
public class Profile
{
public Profile(int id)
{
// C# captures the `id` in a closure.
_lazyAge = new Lazy<int>(
() => GetAgeFromSomewhere(id)
);
}
private Lazy<int> _lazyAge;
public int Age { get { return _lazyAge.Value; } }
public int IsLegal { get { return Age > 18; } }
}
像这样称呼
var profile = new Profile(id);