将setter添加到C#接口中的继承只读属性

Byt*_*der 9 c# inheritance properties interface

我有一个接口,Id只用一个get方法声明一些属性(仅在示例中缩写).实现此接口的类不必为此属性提供公共setter:

public interface IMetadataColumns
{
    Int32 Id { get; }
}
Run Code Online (Sandbox Code Playgroud)

现在我需要另一个具有相同属性的接口,但现在它们都必须都是可写的.所以我添加了一个继承旧的接口的新接口,其中每个属性也有一个setter:

public interface IMetadataColumnsWritable : IMetadataColumns
{
    Int32 Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio现在强调了这一点,并警告我new如果隐藏旧属性,则使用该关键字.


我现在该怎么办?我有实现IMetadataColumns接口的类,需要一些属性是只读的,但我也有其他类,其中同样的属性也必须是可写的.

我想隐藏一个属性听起来不像是要走的路......

Gro*_*roo 15

当涉及接口时,new关键字并不意味着您以与类相同的意义隐藏属性.

您的类实现IMetadataColumnsWritable只有一个Id,无论您是否将它转换为基IMetadataColumns接口(除非您为readonly属性添加显式实现 - 但这不是必需的,并且只允许在这种情况下出错).

换句话说,你可能有:

// this interface is public, and it allows everyone to read the Id
public interface IMetadataColumns
{
    int Id { get; }
}

// this one is writeable, but it's internal
internal interface IMetadataColumnsWritable : IMetadataColumns
{
    // we need to use 'new' here, but this doesn't mean
    // you will end up with two getters
    new int Id { get; set; }
}

// internal implementation is writeable, but you can pass it 
// to other assemblies through the readonly IMetadataColumns 
// interface
internal class MetadataColumns : IMetadataColumnsWritable
{
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

因此,除非您将readonly属性明确地实现为单独的属性,否则您将只有一个属性,无论您使用哪个接口来访问它:

var columns = new MetadataColumns { Id = 5 };

var x = (columns as IMetadataColumns).Id;
var y = (columns as IMetadataColumnsWritable).Id;

Debug.Assert(x == y);
Run Code Online (Sandbox Code Playgroud)

new另一方面,在大多数情况下,我不建议使用关键字隐藏类中的成员,因为它基本上创建了一个全新的成员,恰好被称为基类中的不同成员.