属性:私有方法还是私有get/set?

6
如果我想将类中的属性设置为私有,以便只能在该类中使用和设置该属性,那么什么是更好的方式?这个问题可以通过使用private关键字来解决。
public string Name { private get; private set }

或者

private string Name { get; set }

嗯,还有这个

private string Name { private get; private set }

你想将属性设置为类的私有变量吗? - Kundan Singh Chouhan
@KundanSinghChouhan 是的,我想是这样...不确定我理解你想要什么 ^^ - silla
@Sila 我已经添加了我的答案。请看一下。 - Kundan Singh Chouhan
2
请先尝试编译。在弄清哪个是“更好”的问题之前,首先要回答的是哪一个可以编译。 - O. R. Mapper
1
所有的例子都在 set 后面缺少了分号 ;。但即使加上分号,只有第二个是合法的(请参见我的答案)。 - Jeppe Stig Nielsen
7个回答

18
值得注意的是,最初 C# 不允许在 getter 或 setter 上设置不同的访问级别,因此唯一可能的选择是:
public string Name { get; set; }
protected internal string Name { get; set; }
internal string Name { get; set; }
protected string Name { get; set; }
private string Name { get; set; }

(说起来,你以前不能使用自动属性,总是要自己编写从后备字段读取和写入的代码,但我们将忽略这一点,因为这样可以使例子更短)。

通常有必要为两者设置不同的访问级别,最常见的情况是将setter设为比getter更严格限制,所以会有以下代码:

public string Name { get; private set; }

被引入了。

现在,通过这个推论,允许下面的操作似乎是足够合理的:

public string Name { private get; private set; }
private string Name { private get; private set; }

然而,这两个表达式分别代表什么?

第二个表达式其实并不算太糟糕,只是过于重复了。不过,很可能出现了某些混乱的想法(最可能是未完整重构)。优秀的代码不仅要让计算机执行任务,还要清晰地表达正在做什么(甚至更为重要),最好让它表达得清清楚楚。

因此,如果你最终得到 { private get; private set; } 这样的东西,那么值得再次审视并考虑你真正想表达的内容。幸好这是一个编译器错误。

第一个表达式更糟糕。它的意思是“这个属性是公开的,除了设置器是私有的,获取器也是私有的”。这不是一个例外,“除了所有时间都是这样”并不能表达任何实际意义。双倍欢呼,编译器没有让我们这样做。


只是为了追求严谨:如果在getter或setter上没有指定不同的访问权限,那么还有第五种可能性:protected internal string Name { get; set; } - Jeppe Stig Nielsen
@JeppeStigNielsen 是的。我有一点想法,即 protected internal 在 C#1.0 中不存在,是后来加入的,但快速搜索似乎表明它一直存在。 - Jon Hanna
“internal”现在被错误地标记为“private”。 - Jeppe Stig Nielsen
@JeppeStigNielsen 哈哈。有时候应该就让事情自然发展。 - Jon Hanna
阅读很不错,虽然对于新手来说,介绍最明显的用法可能会很方便:public string name { get; private set} 的意思是类可以读取此属性,但类本身设置它。这可以通过构造函数或此类内部方法的结果来实现。 - Peter

9

你是否尝试编译示例代码?只有中间的一个才能被翻译。

如果你想指定额外的辅助级别关键字,只能在其中一个访问器(getter / setter)上这样做,而此访问器的级别必须比整个属性的可访问性更加严格。

在此处你可以查看规则: 限制访问器的可访问性


是的,你说得对。不知为何,如果我使用private get; private set;编译会失败,只有当我将其用于get或set中的一个时才能成功。 - silla
@silla 这是因为您正在使用一个访问修饰符设置属性,而使用另一个访问修饰符设置所有可能的访问器。将其设置为公共的,并使用私有的get和set会抵消公共部分,因此它不会编译。如果您将其设置为私有,则get和set将自动变为私有,因此无需设置它们... - John Demetriou

1
public string Name { get; private set; }

我认为这是您想要做的事情。

如果您只想让您的类看到它,那么在属性为公共属性时尝试使其变为私有属性是没有意义的。在这种情况下,您应该使用:

private string Name { get; set; }

更新:第二个例子肯定是你想要的。

0
对于私有成员,您不需要定义访问器。只需这样做:
private string _name;

0

更好的方式取决于你想要什么:

public string Name { private get; private set } 这个属性是public,但没有人可以读取或写入它,除了类本身。这完全没有用,所以只需使用private string Name { get; set }

一般来说,如果您将属性视为一对方法(实际上就是这样),

private string get_Name() {  }

private string set_Name(value) {  }

希望你能明白为什么有可能将这些标识符应用于属性的get/set方法。


顺便说一下,我不是那个给你点踩的人。我想你的意思是 private void set_Name(string value) { } - Hand-E-Food
public string Name { private get; private set; } won't compile Cannot specify accessibility modifiers for both accessors of the property or indexer 'Program.Name' - Alex78191

0

看起来你想要

private string name;

public string Name

{

    get { return name; }

    set { name = value; }

}

这将允许您访问 private string Name


0

确实如此, 这就是OOP中私有分类器的定义:只允许在拥有该私有成员的类的方法和范围内进行访问。因此,如果您的目的是禁用任何其他访问特定类成员的方式,并声称它为:

private <Type_name> <member_identifier> ; 

这是最简单的,足以使其如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接