【问题标题】:Using {set; get;} instead of {get; set;}使用 {set; get;} 而不是 {get;放;}
【发布时间】:2013-10-21 22:56:30
【问题描述】:

在 C# 及其近亲语言中,我们总是使用

public string SomeString { get; set;}

但你也可以使用(我最近才发现这个,在玩弄编译器的时候)

public string SomeString { set; get; }

我没有接受过任何正式的编程培训,一切都是自学的。我一直在使用{ get; set; },没有任何想法,就像我们使用1 + 1 = 2一样{ get; set; }的顺序只是一个约定还是有必要保持这个顺序,或者它是C历史过去时代的一些残余,就像这样我们定义了从正极流向负极的常规电流,而实际上相反?

【问题讨论】:

  • 修复您的第二个代码示例;你已经跳过了变量名。
  • @Dariusz 编辑问题不是更容易,而不是发表评论请求 OP 编辑​​它吗?
  • @DavidArno 社区在编辑问题代码时皱眉头。搜索元。虽然这是一个相当明显的案例,但我不能 101% 确定这不是错误。
  • @Dariusz,谢谢,我不知道。我一直在天真地编辑与问题无关的不良缩进和明显的拼写错误。如果那是错误的做法,我最好停下来。
  • @DavidArno 我并不是说我认为你的做法是错误的。我只是不喜欢冒险。如果这是一个答案,我也会编辑代码。

标签: c# oop properties


【解决方案1】:

只是一个约定,您可以在定义参数时使用这些中的任何一个:

public string SomeString { get; set; }
public string SomeString2 { set; get; }
    
public string someString2;

public string SomeString21
{
    get { return someString2; }
    set { someString2 = value; }
}

public string SomeString22
{
    set { someString2 = value; }
    get { return someString2; }
}

public string SomeString23
{
    set { someString2 = value; }
}

public string SomeString24
{
    get { return someString2; }
}

【讨论】:

    【解决方案2】:

    正如其他人已经指出的那样,没有区别,只是一种约定。但是为了证明这一点,你可以看看编译器实际上是如何处理你的代码的,给定以下内容:

    public class C 
    {
        public string SomeString { get; set;}
        public string SomeString2 { set; get; }
    }
    

    这将被视为:

    public class C
    {
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string <SomeString>k__BackingField;
    
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string <SomeString2>k__BackingField;
    
        public string SomeString
        {
            [CompilerGenerated]
            get
            {
                return <SomeString>k__BackingField;
            }
            [CompilerGenerated]
            set
            {
                <SomeString>k__BackingField = value;
            }
        }
    
        public string SomeString2
        {
            [CompilerGenerated]
            get
            {
                return <SomeString2>k__BackingField;
            }
            [CompilerGenerated]
            set
            {
                <SomeString2>k__BackingField = value;
            }
        }
    }
    

    如您所见,编译器生成了一个新的BackingField,两个属性的主体完全相同。

    reference

    【讨论】:

      【解决方案3】:

      Internally Get and Set are methods这样的

      private PropertyType Get() {}
      private Set(value as PropertyType) {} 
      

      由于方法声明的顺序并不重要,所以这里也是如此。

      MSDN:

      get 访问器的主体类似于方法的主体。它必须返回属性类型的值。


      set 访问器类似于返回 void 的方法。它使用一个名为 value 的隐式参数,其类型是属性的类型。

      【讨论】:

        【解决方案4】:

        没有区别。

        就好像你在你的类体中首先实现了getter,然后是setter。这些功能仍然会完全一样:

        public String getSomeString() { return someString; }
        public void setSomeString(String value) { someString=value; }
        

        是否按那个顺序写

        public void setSomeString(String value) { someString=value; }
        public String getSomeString() { return someString; }
        

        或相反。他们不会吗?

        不过,我建议在您的代码中坚持一个顺序。熵越少越好:)

        【讨论】:

          【解决方案5】:

          没有区别。

          根据 C# 语言规范 http://msdn.microsoft.com/en-us/library/ms228593.aspx,10.7.2 访问器(第 324 页)

          属性的访问器声明指定可执行文件 与读取和写入该属性相关的语句。

          访问器声明:

          get-accessor-declaration   set-accessor-declaration
          set-accessor-declaration   get-accessor-declaration
          

          如图所示,任一顺序都具有相同的效果

          【讨论】:

            【解决方案6】:

            { get; set; } 只是一个快捷方式,因此您不必为要公开的每个字段编写 getter 和 setter。和你写的时候一样

            public string GetSomeString() { }
            public void SetSomeString(string value) { } 
            

            重要的是,你先写哪一个?当然不是。

            【讨论】:

              【解决方案7】:

              这纯粹是一种约定。它们出现的顺序没有区别。

              【讨论】:

              • 这与您重载ToString()GetHashCode() 的顺序一致。属性访问器只是 get_varname/set_varname 方法的快捷方式。
              • 小心“只是捷径”的说法。我不能编写方法 get_X() 然后将其作为 X 引用。属性的概念存在于 CLR 中,因此 X 变成了带有“我是属性”元数据的 get_X()。
              • 我很抱歉。我不是在推断有直接的相关性,只是深入了解幕后。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-08-04
              • 2010-09-07
              • 1970-01-01
              • 2016-12-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多