C# {get;set;}和访问修饰符

C# {get;set;}和访问修饰符,c#,C#,我刚刚开始学习c#,我正在努力学习getter和setter速记 据我所知,以下两种方法是等效的。这是正确的吗 //Method 1 public string name { get; set; } //Method 2 private string name public string getName() { return name;} public string setName(string newName) { this.name = newName; } private int ma

我刚刚开始学习c#,我正在努力学习getter和setter速记

据我所知,以下两种方法是等效的。这是正确的吗

//Method 1
public string name { get; set; }

//Method 2
private string name
public string getName() { return name;}
public string setName(string newName) { this.name = newName; }
private int maxTime;
public int MaxTime{ get; set; }
其次,如果我们希望在getter/setter和实例变量上使用不同的访问修饰符,这是如何工作的。下面的代码错误告诉我访问器必须比属性更严格,并且我不能为访问器指定修饰符。有人能澄清一下吗

private int maxTime { public get; public set; }
编辑:为了澄清,我没有具体的目标,只是为了理解。我不明白这个速记符号的作用。在其他语言中,我有私有实例变量,并使用公共getter和setter来管理这些实例变量。如果我自己写方法,它允许这样做,但不是用这个简写符号。为什么会这样

编辑2:最后一个问题来检查我的理解。下面的两个代码段都使用属性来管理maxTime变量。两者之间的唯一区别是风格。这是正确的吗

//Method 1
public string name { get; set; }

//Method 2
private string name
public string getName() { return name;}
public string setName(string newName) { this.name = newName; }
private int maxTime;
public int MaxTime{ get; set; }
vs

上述两种方法并不等同

这样比较更准确:

//Method 1
public string name { get; set; }

//Method 2
private string name; // this is private, not public.
public string Name // this is a property, not a method.
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
public int maxTime { get; private set; }
public int MaxTime { get; private set; }
如果您想使用访问修饰符,如将
设置为公共,将
设置为私有,那么您可以这样做:

//Method 1
public string name { get; set; }

//Method 2
private string name; // this is private, not public.
public string Name // this is a property, not a method.
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
public int maxTime { get; private set; }
public int MaxTime { get; private set; }


更多关于幕后编译器魔法的信息。

而不是错误的
private int maxTime{public get;public set;}
, 您可以编写将填充专用字段的属性:

private int maxTime;

public int MaxTime
{
    get { return maxTime; }
    set { maxTime = value; }
}
当您想要在获取或设置maxTime值时应用逻辑时,这非常有用。如果不是,则使用简单的速记属性即可:

public int MaxTime { get; set; }
您可以创建具有公共getter但具有私有setter的属性,如下所示:

//Method 1
public string name { get; set; }

//Method 2
private string name; // this is private, not public.
public string Name // this is a property, not a method.
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
public int maxTime { get; private set; }
public int MaxTime { get; private set; }
这对于只读属性很有用,并且通常在类的构造函数中填充该属性

您甚至可以创建一个属性,其中setter是公共的,而getter是私有的,尽管我无法想象这会有什么有用的场景。此外,代码标准要求这样的东西应该是一种方法,而不是一种属性。

在编辑2中,您的问题的答案是否定的

第一个代码从不更改私有int
maxTime
,而第二个代码则更改。但是,如果在类中只使用属性
MaxTime
,那么它们在功能上是等价的

更新:

由于c#6,您可以在不使用setter的情况下编写速记属性:

public int MaxTime {get;}
这些属性只能在构造函数中初始化,或者像这样硬编码:(也是c#6的一个新特性)

这对于不可变属性很有用(与只读属性不同,初始化后,即使在宿主类内部,此类属性的值也不能更改)

public string name { get; set; }
您拥有的是,它在内部有一个支持私有字段(以及get/set的编译时方法)

在C代码中,这相当于:

private string _name;
public string name
{
    get { return _name; }
    set { _name = value; }
}
在编译时,get/set被转换为方法调用,这与您所拥有的有些类似

用于:

错误很明显,您不能拥有比属性本身更少的限制性访问说明符。例如,如果您希望
public
属性具有
public
get
,但如果您只希望允许从类内部设置属性,则可以执行以下操作:

public int maxTime { get; private set; }

您还应该看到:,如果您遵循它会更好,这样您的属性名称就可以以大写字母开头。

第一种方法就是为自动实现的属性提供C#语法糖。当您编译它时,它提供了相应访问器的实现

第二个例子不同,这里有一个公共范围字段(由于封装的原理,通常为no)还有两种访问变量的方法。语义用法有细微的区别;通常使用属性来公开状态,而方法通常表示该方法背后有一些计算,而不仅仅是返回或更改当前状态(同样,这是一种惯例,而不是一个硬性规则)方法的样式通常为VerbAction命名(publictthinggetathing(){})

自动生成的属性可以有不同的访问修饰符,但只能使get或set的访问性低于整体修饰符

public int X { get; private set; } // OK
public int X { private get; set; } // OK
private int X { public get; public set; } // NOT OK

当使用方法1(公共字符串名称{get;set;})中的属性时,编译器会自动生成一个私有支持字符串变量以及公共getter和setter方法

一般的想法是将字段设置为私有,并且只允许通过公共getter/setter方法进行访问

我建议使用ILDASM仔细阅读生成的IL,它有助于了解引擎盖下发生了什么


第二个错误就是编译器所说的。构造的可见性必须是一致的

为什么要在私有变量上使用public getter/setter?不,这两种方法不一样。请解释您想要做什么,而不仅仅是最终得到什么代码。您不能执行private int maxTime{public get;public set;}因为属性(不是变量!)的外部访问权限比内部访问权限更严格-注:设置不需要公共修饰符最有限的范围优先,正如错误明确说明的那样,而且相当直观。
public
作为
get
/
set
级别总是冗余的;带有
protected
private
集的
公共
属性可能有用不过,在C#中有很多方法可以实现属性,因此,也许只需说明您打算做什么,并且不要陷入将其与其他语言和功能等价物进行比较的泥潭,就可以获得更好的答案