使用 set; get; 而不是 get;放;

Posted

技术标签:

【中文标题】使用 set; get; 而不是 get;放;【英文标题】: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 我并不是说我认为你的做法是错误的。我只是不喜欢冒险。如果这是一个答案,我也会编辑代码。 【参考方案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()。 我很抱歉。我不是在推断有直接的相关性,只是深入了解幕后。

以上是关于使用 set; get; 而不是 get;放;的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们使用 .NET 属性而不是普通的旧 get/set 函数?

JavaBean规范

类中是不是定义了 GET 或 SET

JavaBean规范

JMeter 中是不是有更多线程安全变量可用于 get() 和 set() 变量?

java项目源代码里面的get方法为啥总写在set方法前面 感觉有点不符合逻辑 不是设置之后再获