简体   繁体   English

自动实现的属性如何在 C# 接口中工作?

[英]How do Auto-Implemented properties work in C# interfaces?

If I declare Auto-Implemented properties in C# classes, then public string Property { get; set; }如果我在 C# 类中声明自动实现的属性,则public string Property { get; set; } public string Property { get; set; } public string Property { get; set; } becomes: public string Property { get; set; }变成:

private string _property;

public string get_Property() {
    return _property;
}

public void set_Property(string value) {
    _property = value;
}

which includes a private field string _property .其中包括一个私有字段string _property

If I create an interface, I am allowed to use Auto-Implemented properties like so:如果我创建一个接口,我可以像这样使用自动实现的属性:

string Property { get; set; }

Why can I declare Auto-Implemented properties inside Interface, but I can't use the longer, more verbose syntax that declares private fields?为什么我可以在 Interface 中声明 Auto-Implemented 属性,但我不能使用更长、更详细的语法来声明私有字段? I am aware of the definition that says:我知道这样的定义:

An interface contains only the signatures of methods, properties, events or indexers接口仅包含方法、属性、事件或索引器的签名

Is the private field in interfaces not generated the same as in classes?接口中的私有字段与类中的生成方式不同吗? Is it generated at all?它是完全生成的吗?

Why can I declare Auto-Implemented properties inside Interface为什么我可以在 Interface 中声明 Auto-Implemented 属性

They aren't auto-implemented, it's just that the syntax of a property declaration is identical to the syntax for an auto-implemented property definition .它们不是自动实现的,只是属性声明的语法与自动实现的属性定义的语法相同。

This:这个:

interface IFoo
{
    String Bar { get; set; }
}

Means: " IFoo has a public [1] String property named Bar which has a getter and a setter."意思是:“ IFoo有一个名为Bar公共[1] String属性,它有一个 getter 和一个 setter。”

This:这个:

class Foo
{
    String Bar { get; set; }
}

Means: " Foo has a private [2] String property named Bar which has a getter and a setter, and the getter and setter are both auto-generated by the compiler and operate on a hidden instance field.意思是:" Foo有一个名为Bar私有[2] String属性,它有一个 getter 和一个 setter,getter 和 setter 都是编译器自动生成的,并在隐藏的实例字段上操作。


Note that the syntax used in the interface is unrelated to the syntax used by implementation in the class or struct .请注意,接口中使用的语法与classstruct中的实现使用的语法无关。 So given the same IFoo as above...所以给定与上面相同的IFoo ......

interface IFoo
{
    String Bar { get; set; }
}

...we can have: ...我们可以有:

// Using auto-implemented property:
class Foo2 : IFoo
{
    public String Bar { get; set; }
}
// Using explicit backing field:
class Foo3 : IFoo
{
    private String bar;

    public String Bar
    {
        get { return this.bar; }
        set { this.bar = value; }
    }
}
// Using expression-body syntax with a backing field:
class Foo4 : IFoo
{
    private String bar;

    public String Bar
    {
        get => this.bar;
        set => this.bar = value;
    }
}
// Using explicit interface implementation with a backing field:
class Foo5 : IFoo
{
    private String bar;

    String IFoo.Bar
    {
        get { return this.bar; }
        set { this.bar = value; }
    }
}

// You can also use explicit interface implementation with an auto-implemented property:
class Foo6 : IFoo
{
    String IFoo.Bar { get; set; }
}
// However, if it's a getter-only property you won't be able to set a property value in the constructor - but you can initialize it inline:
interface IReadOnlyFoo
{
    String Bar { get; }
}

class Foo7 : IReadOnlyFoo
{
    String IReadOnlyFoo.Bar { get; } = "foo"; // ok
}

class Foo8 : IReadOnlyFoo
{
    public Foo8()
    {
        this.Bar = "foo"; // <-- Error. `Bar` is not a member of `this`.
        // You also can't cast `(IReadOnlyFoo)this` because `IReadOnlyFoo` does not contain a setter.
    }

    String IReadOnlyFoo.Bar { get; }
}

Is the private field in interfaces not generated the same as in classes接口中的私有字段是否与类中生成的不同

Interfaces don't have fields, interfaces only have virtual methods (or rather: an interface can be thought-of as a single vtable).接口没有字段,接口只有虚拟方法(或者更确切地说: interface可以被认为是单个 vtable)。 Note that internally: properties and events are also fundamentally virtual methods (also note that while internally they're virtual calls, implemented interface methods are not automatically virtual (in the C# sense) in that a subclass of an interface implementation cannot arbitrarily override any interface member [3] .请注意,在内部:属性和事件基本上也是虚拟方法(还要注意,虽然在内部它们是虚拟调用,但实现的接口方法不会自动virtual (在 C# 意义上),因为接口实现的子类不能任意override任何接口成员[3]

Also not to be confused with "Default interface implementations" in C# 8.0 which a more akin to extension methods than treating interfaces as classes, because interfaces still cannot have fields.也不要与 C# 8.0 中的“默认接口实现”混淆,后者更类似于扩展方法而不是将接口视为类,因为接口仍然不能有字段。

You should also familarise yourself with C#'s expression-bodied member syntax (though it isn't used much for property-setters):您还应该熟悉 C# 的表达式主体成员语法(尽管它不常用于属性设置器):

class Foo2
{
    String bar; // this is a private instance field

    String Bar // this is a private instance property
    {
        get => this.bar;
        set => this.bar = value;
    }
}

[1] Disregarding Explicit Interface Implementation, of course. [1] 当然,不考虑显式接口实现。
[2] Class members are private by default if they don't have an explicit access-modifier. [2] 如果类成员没有明确的访问修饰符,则默认情况下它们是私有的。
[3] Subclasses can reimplement an interface which will have the effect of overriding any virtual-calls to that interface member, but only if the member is accessed through an interface reference rather than through an object reference to the class's supertype. [3] 子类可以重新实现一个接口,该接口将具有覆盖对该接口成员的任何虚拟调用的效果,但前提是该成员是通过接口引用而不是通过对类的超类型的对象引用来访问的。

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

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