Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么属性访问器中的访问修饰符应该比属性本身更严格?_C# - Fatal编程技术网

C# 为什么属性访问器中的访问修饰符应该比属性本身更严格?

C# 为什么属性访问器中的访问修饰符应该比属性本身更严格?,c#,C#,在开发我的应用程序时,我有时会想到,我需要一个当前(比如说私有)的属性,但可能以后,当我们需要处理新的场景时,我们可能需要将其设置为公共。但是,即使这会发生,我始终希望二传手保持隐私。我想写这样的代码: private int A { get{return _a;} private set {_a = value;} } private int _a; public int A { get { return _a; } private set { i

在开发我的应用程序时,我有时会想到,我需要一个当前(比如说私有)的属性,但可能以后,当我们需要处理新的场景时,我们可能需要将其设置为公共。但是,即使这会发生,我始终希望二传手保持隐私。我想写这样的代码:

private int A
{
  get{return _a;}
  private set {_a = value;}
}
private int _a;
public int A
{
    get { return _a; }
    private set { 

        if (value < 0 || value > 10)
        {
            throw new ArgumentOutOfRangeException("A");
        }

        _a = value; 
    }
}
编译器抱怨setter上的访问修饰符应该比属性更严格。我需要移除集合上的访问修饰符,但是如果以后我需要将属性升级为公共,我也会公开它的setter


你不认为这是一个警告而不是一个错误更好吗?

如果你将代码改为“公共”,你也可以同时将代码改为“私人设置”

至于这是一个警告,我认为这是有道理的——我不认为只有两次指定
private
(虽然这显然是毫无意义的)。也就是说,我很少遇到这个编译器错误,当我遇到这个错误时,我花了5秒钟来修复它,然后继续


具有讽刺意味的是,我们现在在这个问题和答案上花费的时间比我们在这个错误及其影响上可能花费的时间要长:-)

您的示例中的代码没有意义。如果您的属性是私有的,则setter也是私有的。您只需要在setter上指定访问修饰符,如果setter必须有另一个访问修饰符,那么getter

你不认为这是一个警告而不是一个错误更好吗

不,我认为您最好使用私有变量(
private int\u a;
),并仅在需要时将其升级为具有适当修改器的属性

当然,如果没有setter,就不能像这样使用验证:

private int A
{
  get{return _a;}
  private set {_a = value;}
}
private int _a;
public int A
{
    get { return _a; }
    private set { 

        if (value < 0 || value > 10)
        {
            throw new ArgumentOutOfRangeException("A");
        }

        _a = value; 
    }
}
private int\u a;
公共INTA
{
获取{return\u a;}
私有集{
如果(值<0 | |值>10)
{
抛出新ArgumentOutOfRangeException(“A”);
}
_a=数值;
}
}

但另一方面,一开始就将该房产标记为公共房产并没有什么坏处,是吗?

我想你应该做以下几点

private int _a;
public int A
{
    get { return _a; }
    private set { _a = value; }
}

这使得get访问器是公共的,而set是私有的。

更改这两个修饰符是完全有效的,因此我不会为privat setter操心太多:

public int A
{
  get{return _a;}
  private set {_a = value;}
}
这只是我的猜测,警告来自编译器将属性重新写入IL代码的方式。属性将作为getter和setter方法写入,并使用与属性本身相同的修饰符

如果现在尝试定义私有属性的私有setter,这将转换为:

private private get_A()
{
   return _a;
}

这个双重私有修饰符显然无法编译。

问题的关键是:我可能需要在3个月后将其公开,或者甚至其他人可能需要更改它,但我忘记了/他不知道它的setter应该是私有的。@Alireza我知道这一点,但是,当您编辑代码时,帮助您进行尽可能最小的更改并不是编译器甚至IDE的任务。如果它保持私有是很重要的,那么为它创建一个测试,或者不直接使用类型,而是使用一个接口(它不能公开私有成员)。我同意,但我相信编译器正在推测一些它不应该做的事情。我将尝试解释:假设在设计过程中,我们希望属性得到保护,也希望它可以私下设置。这些是完全不同的需求,编译器尊重这一点。现在,如果两个需求都是私有的,那么它们仍然是两个不同的需求,但是编译器对此不再满意。@Alireza那么在本例中,您将了解您的需求并相应地编写代码。编译器并没有阻止您对这些需求进行编码,而是阻止您按照自己想要的方式进行编码。我不知道为什么它会导致错误,而不是警告,但现在它是这样工作的,我可以看到很多让它保持沉默的理由。你是对的。我通常会尝试预见未来的变化,并以一种错误可能性最小的方式编写代码。我尽可能多地从产品中提取。这就是我喜欢微软产品的地方。我见过的任何其他组件/库都会阻止您对其产品的使用方式做出不必要的假设。这在c#和.Net类库中是最小的。这是非常罕见的例子之一。