【问题标题】:What am I doing wrong with C# object initializers?我对 C# 对象初始化器做错了什么?
【发布时间】:2009-02-17 22:03:23
【问题描述】:

当我在 C# 中使用新的对象初始化器初始化对象时,我无法使用类中的某个属性来执行进一步的操作,我不知道为什么。

我的示例代码:

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

在 Person 类中,x 等于 0(默认):

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

但是 person.Age 确实等于 29。我确信这是正常的,但我想了解原因。

【问题讨论】:

  • 构造函数中的年龄是否应该像您的财产一样全是小写或标题?这可能有助于确定问题
  • 不,应该是年龄。抱歉打错了

标签: c# object-initializers


【解决方案1】:

在构造函数 'public Person()' 完成运行后,为 Name 和 Age 设置属性。

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

等价于

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

所以,在构造函数中,Age 还不会变成 29。

(tempPerson 是您在代码中看不到的唯一变量名称,它不会与以这种方式构造的其他 Person 实例发生冲突。tempPerson 是避免多线程问题所必需的;它的使用确保新对象不会'直到构造函数被执行并且所有的属性都被初始化之后才能被其他线程使用。)


如果你希望能够在构造函数中操作 Age 属性,那么我建议你创建一个以年龄为参数的构造函数:

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

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

【讨论】:

  • 虽然“在构造函数 'public Person()' 完成运行后,为 Name 和 Age 设置属性。”
  • @Juan:您对“这是错误的”的 cmets 有点不友好。虽然这个答案在不引用临时变量方面有点不准确,但就所提出的问题而言并没有错。尽量礼貌一点,以免下次成为你的问题或答案。
  • @Jeff:我们在这里回答问题,通常以不平静的感觉为代价。这就是极客的生活,也是我们不做销售的原因。
【解决方案2】:

请注意,作为一个重要的技术细节:

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

相当于:

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

但不等同于:

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

【讨论】:

  • 为什么这很重要?我看不出效果有什么不同。
  • +1 只是打败了我......你是对的 wcoenen,你不会看到区别......直到另一个线程尝试读取 Person.Name - 但实际上不是设置是因为 0.Name 是...
  • 是的,多线程是这个技术细节很重要的原因。
【解决方案3】:

您的代码行与以下内容相同:

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

等同于:

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

如您所见;当构造函数执行时,Age 尚未设置。

【讨论】:

  • "构造函数执行时,Age还是29"?真的吗?
  • 哎呀-你知道我的意思;-p
  • 我能看到的唯一“错误”是瞬态变量;对于提出的问题,我觉得这是一个不必要的细节。
【解决方案4】:

从技术上讲,这段代码:

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

与此代码相同:

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

这与其他人发布的内容略有不同:

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

如果您的应用程序使用多线程,则此差异至关重要。

【讨论】:

    【解决方案5】:

    您似乎正试图在对象的构造函数中访问Age。对象初始化器的值在构造函数执行后才会被设置。

    试试这个:

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

    编辑以回应评论

    如果您需要在构造函数本身中访问Age,那么您需要创建一个带有所需参数的显式构造函数,并使用它而不是对象初始值设定项语法。例如:

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

    【讨论】:

    • 是的,这对我有用,但是当我还在构造函数中时,我想对 Age 做一些事情
    【解决方案6】:

    嗯,正如其他人所说,无参数构造函数首先被执行,因此你很困惑。

    不过,我不得不问一下,您是否为 Age 变量设置了字段而不是自动属性?

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

    你可以使用_age而不是x,如果这已经足够了,或者如果你真的需要使用x

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

    哪个更合适。

    【讨论】:

    • 我使用了 Public int Age {get; set;} - 自动属性
    • dmce -- 准确地说。 “手动”或“传统”属性会让您更轻松地解决此问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    相关资源
    最近更新 更多