What am I doing wrong with C# object initializers?

喜欢而已 提交于 2021-02-04 15:22:07

问题


When i initialize an object using the new object initializers in C# I cannot use one of the properties within the class to perform a further action and I do not know why.

My example code:

Person person = new Person { Name = "David", Age = "29" };

Within the Person Class, x will equal 0 (default):

public Person()
{
  int x = Age; // x remains 0 - edit age should be Age. This was a typo
}

However person.Age does equal 29. I am sure this is normal, but I would like to understand why.


回答1:


The properties get set for Name and Age after the constructor 'public Person()' has finished running.

Person person = new Person { Name = "David", Age = "29" };

is equivalent to

Person tempPerson = new Person()
tempPerson.Name = "David";
tempPerson.Age = "29";
Person person = tempPerson;

So, in the constructor Age won't have become 29 yet.

(tempPerson is a unique variable name you don't see in your code that won't clash with other Person instances constructed in this way. tempPerson is necessary to avoid multi-threading issues; its use ensures that the new object doesn't become available to any other thread until after the constructor has been executed and after all of the properties have been initialized.)


If you want to be able to manipulate the Age property in the constructor, then I suggest you create a constructor that takes the age as an argument:

public Person(string name, int age)
{
   Name = name;
   Age = age;

   // Now do something with Age
   int x = Age;
   // ...
}



回答2:


Note, as an important technical detail, that:

Person person = new Person { Name = "David", Age = "29" };

is equivalent to:

Person <>0 = new Person(); // a local variable which is not visible within C#
<>0.Name = "David";
<>0.Age = "29";
Person person = <>0;

but is not equivalent to:

Person person = new Person();
person.Name = "David";
person.Age = "29";



回答3:


Your line of code is identical to:

Person person = new Person() { Name = "David", Age = "29" };

which is identical to:

Person person = new Person();
person.Name = "David";
person.Age = "29";

As you can see; when the constructor executes, Age is not yet set.




回答4:


Technically, this code:

Person person = new Person { Name = "David", Age = 29 };

is identical to this code:

Person tmpPerson = new Person();
tmpPerson.Name = "David";
tmpPerson.Age = 29;
Person person = tmpPerson;

which is slightly different than what others have posted:

Person person = new Person();
person.Name = "David";
person.Age = 29;

This difference is crucial if your application is using multi-threading.




回答5:


It looks like you're trying to access Age in the object's constructor. The object initializer values won't be set until after the constructor has executed.

Try this:

Person person = new Person { Name = "David", Age = 29 };
int x = person.Age;

EDIT in response to comment

If you need access to Age in the constructor itself then you'll need to create an explicit constructor with the required parameters, and use that instead of the object initializer syntax. For example:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;

        int x = Age;  // will be 29 in this example
    }
}

Person person = new Person("David", 29);



回答6:


Well, as others said, the parameterless constructor got executed first, hence your quandary.

I do have to ask however, if you've set a field instead of an automatic property for your Age variable?

public class Person
{
    private int _age;

    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
 }

You could use _age instead of x if that's enough, or if you really need to use x:

public class Person
{
    private int _age;
    private int x;

    public int Age
    {
        get { return _age; }
        set 
        { 
            _age = value;
            x = _age;
        }
    }
 }

Whichever is more appropriate.



来源:https://stackoverflow.com/questions/558916/what-am-i-doing-wrong-with-c-sharp-object-initializers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!