【问题标题】:What do you think of using properties as object initializers in C#;您如何看待在 C# 中使用属性作为对象初始值设定项?
【发布时间】:2008-09-17 23:57:35
【问题描述】:

我想知道人们对在 C# 中使用属性作为对象初始值设定项有何看法。出于某种原因,它似乎打破了构造函数的基本用途。

一个例子...

public class Person
{
    string firstName;
    string lastName;

    public string FirstName
    {
      get { return firstName; }
      set { firstName = value; }
    }

    public string LastName
    {
      get { return lastName; }
      set { lastName= value; }
    }
}

然后用.....进行对象初始化

Person p = new Person{ FirstName = "Joe", LastName = "Smith" };
Person p = new Person{ FirstName = "Joe" };

【问题讨论】:

    标签: c#


    【解决方案1】:

    您在这里看到的是编译器提供的一些语法糖。在引擎盖下它的真正作用是这样的:

    Person p = new Person(FirstName = "Joe", LastName = "Smith");

    Person _p$1 = new Person();
    _p$1.FirstName = "Joe";
    _p$1.LastName = "Smith";
    Person p = _p$1;
    

    所以恕我直言,您并没有真正破坏任何构造函数的基础,而是使用了一个很好的语言工件来简化可读性和可维护性。

    【讨论】:

      【解决方案2】:

      对象初始值设定项绝不会取代构造函数。构造函数定义了创建类实例必须遵守的约定。

      C# 语言中对象初始化器的主要动机是支持Anonymous Types

      var v = new { Foo = 1, Bar = "Hi" };
      Console.WriteLine(v.Bar);
      

      【讨论】:

        【解决方案3】:

        恕我直言,它很甜蜜。大多数对象都使用默认构造函数进行了更新,并且必须在它们准备好运行之前设置一些属性;所以对象初始化器可以更容易地针对大多数对象进行编码。

        【讨论】:

          【解决方案4】:

          构造函数应该只有真正需要来构造对象的参数。对象初始化器只是为属性赋值的一种便捷方式。我尽可能使用对象初始化器,因为我认为这是一种更简洁的语法。

          【讨论】:

            【解决方案5】:

            既然您已经在使用新的 C# 语法,不妨也使用自动属性,让您的代码更加甜美:

            而不是这个:

            string firstName;
            
            public string FirstName
            {
              get { return firstName; }
              set { firstName = value; }
            }
            

            使用这个:

            public string FirstName { get; set; }
            

            【讨论】:

              【解决方案6】:

              我认为总的来说它很有用,尤其是在与自动属​​性一起使用时。 当属性做的不仅仅是获取/设置时,它可能会令人困惑。 希望这将导致更多的方法,并减少属性的滥用。

              【讨论】:

                【解决方案7】:

                不是您最初的问题,但仍然...

                你的类声明可以写成:

                public class Person
                {
                    public string FirstName { get; set; }
                    public string LastName {get; set; }
                }
                

                如果是我的代码,我可能会有一个 Name 对象,其中包含 First 和 Last 字段。

                【讨论】:

                  【解决方案8】:

                  对于从语言集成查询(linq)返回的投影类来说也是非常必要的

                  var qry = from something in listofsomething
                            select new {
                                          Firstname = something.FirstName,
                                          Lastname = something.Surname
                                        }
                  

                  【讨论】:

                  • 您可能是指匿名对象列表(代替“投影类”)。 :)
                  【解决方案9】:

                  补充 Nescio 的想法 - 我建议在代码审查中积极寻找属性访问器中昂贵的透明操作,例如DB 往返。

                  【讨论】:

                    【解决方案10】:

                    对象初始化器有助于降低编码复杂性,因为您不需要创建六个不同的构造函数来为属性提供初始值。在我的书中,任何减少冗余代码的事情都是积极的。

                    我认为向语言添加该功能的主要原因是支持anonymous types 用于 LINQ。

                    【讨论】:

                      【解决方案11】:

                      如果您想强制使用构造函数,您可以将对象的默认无参数构造函数设置为私有,而只保留一些强制构造函数:

                      public class SomeObject
                      {
                          private SomeObject()
                          {}
                      
                          public SomeObject(string someString) //enforced constructor
                          {}
                      
                          public string MyProperty { get; set; }
                       }
                      

                      使用上面的定义,这会引发错误:

                      var myObject = new SomeObject { MyProperty = "foo" } //no method accepts zero arguments for constructor
                      

                      当然,这不能适用于所有情况。例如,序列化要求您有一个非私有的默认构造函数。

                      【讨论】:

                        【解决方案12】:

                        我对他们不满意。我认为它们在构造函数中没有一席之地,或者 MS 应该返回并重构它们以允许您以私人方式使用它们。如果我构造一个对象,我想传入一些 PRIVATE 数据。我希望它从外部世界设置一次,仅此而已。使用对象初始化器,您可以修改传递给构造函数的值。

                        也许将来他们会改变这一点。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2016-12-27
                          • 2011-04-08
                          • 2011-08-01
                          • 2015-06-25
                          • 1970-01-01
                          • 2011-09-30
                          • 2022-10-04
                          • 1970-01-01
                          相关资源
                          最近更新 更多