2016-04-28 5 views
6

getメソッドを使用していくつかのプロパティ(例ではIdに短縮)を宣言するインターフェイスがあります。このインタフェースを実装するクラスは、このプロパティのパブリックセッターを提供する必要はありません。C#インターフェイスの継承された読み取り専用プロパティにセッターを追加する

public interface IMetadataColumns 
{ 
    Int32 Id { get; } 
} 

は今、私は、同じプロパティを持つ別のインターフェイスが必要ですが、今、彼らはすべて同様に書き込み可能でなければなりません。

public interface IMetadataColumnsWritable : IMetadataColumns 
{ 
    Int32 Id { get; set; } 
} 

Visual Studioは今、このことを強調し、古い性質が意図していた隠れている場合newキーワードを使用するように私に警告している。だから私は、各プロパティもセッターを持っている古いものから継承する新しいインターフェイスを追加しました。


ここで何をすればよいですか? IMetadataColumnsインターフェイスを実装するクラスがあります。このクラスには、一部のプロパティを読み込み専用にする必要がありますが、同じプロパティに書き込み可能でなければならない他のクラスもあります。私は何とか移動するための方法が気に入らない音財産を隠し推測

...

+0

私はプロパティを隠すのが正しい方法だと思っていますが、IMetadataColumnsを実装しているクラスはまだ読み取り専用のプロパティを持ち、IMetadataColumnsWritableを実装するクラスは読み書き可能なプロパティを持ちます。 –

答えて

11

インターフェイスが含まれている場合、newキーワードは、がクラスと同じ意味でを隠すことを意味しません。しかし、これは必要ないとだけできるようになる - あなたは読み取り専用プロパティの明示的な実装を追加ない限りIMetadataColumnsWritableを実装

あなたのクラスでは、唯一の(関係なく、あなたがベースIMetadataColumnsインターフェイスにキャストするかどうかのか、を1 Idを持っていますこの場合のエラーの場合)。言い換えれば

、あなたが持つかもしれない:

// 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; } 
} 

をので、あなたが明示的に別の一つとしてReadOnlyプロパティを実装していない限り、あなただけの単一のプロパティを持つことになり、どちらのインタフェースあなたはそれにアクセスするために使用します。

newキーワードを使用して、クラス内のメンバーを非表示に
var columns = new MetadataColumns { Id = 5 }; 

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

Debug.Assert(x == y); 

は、他の一方で、それは基本的に完全に新しいメンバーが作成されますので、私はは、ほとんどの場合にはお勧めしませんものですこれは基本クラスの別のメンバーと同じように呼び出されます。

+0

@PatrickHofman:明示的に他のものを実装する場合のみ – Groo

+0

これは、 'new'キーワードを使って読み込み専用の宣言を隠す書き込み可能なインターフェースを実装しているクラスを持っている場合、' IMetadataColumns'にキャストされたそのクラスのインスタンスは、 IMetadataColumnsWritable'にキャストされているかどうか? –

+1

いいえ、@ByteCommanderは1つだけです –

2

は、あなたは確かにここにnewキーワードを使用する必要があります。クラスの実装では、両方のプロパティを実装する必要があります(プロパティを実際に隠すわけではないため)。それらの戻り値の型が異なる場合は、少なくとも1つを明示的に実装する必要があります。

public class X : IMetadataColumnsWritable 
{ 
    public int Id 
    { 
     get; 
     set; 
    } 

    // only necessary if you have to differentiate on the implementation. 
    int IMetadataColumns.Id 
    { 
     get 
     { 
      return this.Id; // this will call the public `Id` property 
     } 
    } 
} 
+0

これは、ロジックがなく、読み書き可能なプロパティが値を読み取るときに同じでなければ、 'int IMetadataColumns.Id {...} 'の部分は必要ないと言っていますか? –

+0

はい、そうです。 @ByteCommander –

1

getterの明示的な実装を使用すると、パブリックバージョンへのバージョン転送のみが機能しますか?

int IMetadataColumns.Id { 
    get { 
    return this.Id; 
    } 
} 

public Id { 
    get { … } 
    set { … } 
} 

あなたは公共のバージョンがnewする必要がないかもしれませんが、明示的なバージョンは、タイプIMetadataColumnsの参照によってピックアップされます。

+0

明示的な 'Id'に' this.Id'をキャストする必要はありません。 –

+0

@PatrickHofman私はそれを守備と一貫性の尺度として含める傾向があります(ただし、時には不必要です. – Richard

+0

)インターフェイスを変更すると問題が発生する可能性があります。 –

関連する問題