简体   繁体   English

为什么属性只能包含C#中接口类型的setter?

[英]Why property can be contain only setter in interface type in C#?

I wonder why in C# it is not allowed to use only { set } property in auto-generated property in class type like: 我想知道为什么在C#中不允许在类类型的自动生成属性中仅使用{set}属性,如:

class Person {
    public string Name { set; } // Compile-time error
}

However, it is allowed in interface type: 但是,在接口类型中允许:

interface IPerson {
    string Name {set;} //Allowed
}

I read similar question here , it is very rare practice - what I understand, but I wonder why CLR even allow to do it? 在这里读到类似的问题,这是非常罕见的实践 - 我理解,但我想知道为什么CLR甚至允许这样做?

For one simple reason. 原因很简单。 If you're using an Auto implemented property (Hidden private field generated). 如果您正在使用自动实现的属性(生成隐藏的私有字段)。 Then why would you need to set a value that you would never be able to get (and subsequently use). 那么为什么你需要设置一个你永远无法获得的值(并随后使用)。

For the Interface, you're not using an auto implemented property, it is just a contract specifying that the implementation class should have a string property named Name that should implement a Setter method. 对于Interface,您没有使用自动实现的属性,它只是一个契约,指定实现类应该有一个名为Name的字符串属性,该属性应该实现Setter方法。 So, you can do this: 所以,你可以这样做:

interface IPerson
{
    string Name { set; }
}

class Person : IPerson
{
    private string _name;
    public String Name
    {
        set { _name = value; }
    }
}

So in conclusion, the C# compiler is trying to prevent us from doing something that doesn't make any sense which is: Providing an auto set method for a private hidden field that can never be get. 总而言之,C#编译器试图阻止我们做一些没有任何意义的事情: 为永远无法获取的私有隐藏字段提供自动设置方法。

Because what is the point of a property you can assign a value to but have no way to observe it? 因为属性的重点是你可以为一个值赋值但却无法观察它?

The following is perfectly legal 以下是完全合法的

class Person {
    private string _name;
    public string Name { set { _name = value } }
}

The reason the auto property doesn't let you do it is because you could never get the value out after it was written, with a manual implemented property you have the chance to set the value to some other field. auto属性不允许你这样做的原因是因为你在编写之后永远无法获得值,使用手动实现的属性你有机会将值设置为其他字段。

The reason interfaces allow it is so the interface can describe manually implemented versions or auto implemented ones with public string Name {private get; set;} 接口允许它的原因是接口可以描述手动实现的版本或自动实现的版本具有public string Name {private get; set;} public string Name {private get; set;} . public string Name {private get; set;}

You're using an autoproperty in your class, which is defined as having a hidden private field that is accessible using a getter. 您在类中使用了autoproperty,它被定义为具有可使用getter访问的隐藏私有字段。

If you're just using a normal property, you can absolutely have only a setter: 如果你只是使用普通的属性,你绝对只能有一个setter:

    public string Name {
        set {
            Console.WriteLine("hi");
        }
    }
class Person {
    public string Name { set; } // Compile-time error
}

The backing field is inaccessible, so there is no way to get it. 支持字段无法访问,因此无法获取它。 It's explained in the C# specification that since there is no point in having one without the other, it is disallowed. 在C#规范中对此进行了解释,因为没有一个没有另一个没有意义,所以不允许这样做。

Because the backing field is inaccessible, it can be read and written only through the property accessors, even within the containing type. 由于支持字段不可访问,因此只能通过属性访问器读取和写入,即使在包含类型中也是如此。 This means that automatically implemented read-only or write-only properties do not make sense, and are disallowed. 这意味着自动实现的只读或只写属性没有意义,并且是不允许的。 It is however possible to set the access level of each accessor differently. 但是,可以不同地设置每个访问者的访问级别。

The compiler team made a call that it would be better to not allow it, since there is no point and by allowing it, developers can potentially write more error prone code. 编译器团队打电话说最好不允许它,因为没有意义,通过允许它,开发人员可能会编写更多容易出错的代码。

They make the same judgement call in other areas of the language too, such as not allowing fall through most of the time in case statements. 他们也在语言的其他方面做同样的判断调用,例如在案例陈述中不允许大部分时间掉头。 (you can fall through a case with no code in it). (你可以通过一个没有代码的案例)。 Technically, in that instance you could say it provides benefit, but they felt that the benefit did not outweigh the potential error cost. 从技术上讲,在这种情况下,你可以说它提供了好处,但他们认为这种好处并没有超过潜在的错误成本。

The interface is only to make sure that your class is implementing the method. 该接口仅用于确保您的类正在实现该方法。 However, when you are creating a class, there is no point of having a property that you can never get 但是,当您创建一个类时,没有必要拥有一个永远无法获得的属性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM