Can the properties inside the object initializer refer to each other?

Is it possible that the properties refer to each other during the creation of a dynamic object of an anonymously typed object (i.e. inside the object initializer)? In my simplified example below, you need to reuse the Age property without making the second heavy call to GetAgeFromSomewhere() . Of course, this will not work. Any suggestion on how to do this?

 var profile = new { Age = GetAgeFromSomewhere(id), IsLegal = (Age>18) }; 

It is possible that this is possible or impossible with <dynamic objects anonymously typed object initializers ?

+6
source share
3 answers

Unfortunately, this is not possible, even with clearly typed objects. This is due to the way object initializers work. For instance:

 public class MyClass { public int Age = 10; public bool IsLegal = Age > 18; } 

Sets this compiler error to "IsLegal":

Error 1 The field initializer cannot refer to non-static fields, method or property "MyClass.Age" ...

A field initializer cannot reference other non-static fields, and since anonymous types do not create static fields, you cannot use the value of one field to initialize another. The only way around this is to declare variables outside of the anonymous type and use them inside the initializer.

 int age = GetAgeFromSomewhere(id); var profile = new { Age = age, IsLegal = age > 18 }; 
+7
source

Do not complicate things, try

 //Create a variable var age = GetAgeFromSomewhere(id); var profile = new { Age = age, IsLegal = age>18 } 
+5
source

What you want is not possible in object intializers. You cannot read the properties of an initialized object. (It doesn't matter if the type is anonymous or not.)

Create a class instead

 public class Profile { public Profile(int id) { Age = GetAgeFromSomewhere(id); } public int Age { get; private set; } public int IsLegal { get { return Age > 18; } } } 

Or get age in a lazy way:

 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; } } } 

or using the Lazy<T> class (starting with 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; } } } 

Call it like this:

 var profile = new Profile(id); 
+2
source

Source: https://habr.com/ru/post/985423/


All Articles