简体   繁体   English

C#对象初始化程序在做什么?

[英]What am I doing wrong with C# object initializers?

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. 当我使用C#中的新对象初始化程序初始化对象时,无法使用该类中的属性之一执行进一步的操作,我也不知道为什么。

My example code: 我的示例代码:

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

Within the Person Class, x will equal 0 (default): 在Person类中,x等于0(默认值):

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. 但是person.Age等于29。我确定这是正常的,但我想了解原因。

The properties get set for Name and Age after the constructor 'public Person()' has finished running. 在构造函数“ public Person()”完成运行之后,将为Name和Age设置属性。

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. 因此,在构造函数中,Age不会成为29岁。

(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.) (tempPerson是您在代码中看不到的唯一变量名称,不会与以此方式构造的其他Person实例冲突。tempPerson是避免多线程问题所必需的;它的使用可确保新对象不会变成在执行构造函数之后以及初始化所有属性之后才可用于任何其他线程。)


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: 如果您希望能够在构造函数中操作Age属性,那么建议您创建一个以age作为参数的构造函数:

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

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

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

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. 构造函数执行时,尚未设置Age

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. 如果您的应用程序使用多线程,则此区别至关重要。

It looks like you're trying to access Age in the object's constructor. 似乎您正在尝试在对象的构造函数中访问Age 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. 如果您需要在构造函数本身中访问Age ,则需要使用必需的参数创建一个显式构造函数,并使用它代替对象初始化器语法。 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);

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? 但是,我确实要问,是否为Age变量设置了字段而不是自动属性?

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 : 你可以使用_age ,而不是x ,如果这就够了,或者如果你真的需要使用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. 哪个更合适。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM