1

次のインターフェースを検討してください

public interface ICustomData
{
    String CustomData { set; get; }
}

MSDNのドキュメントによると、インターフェイスのメンバーは自動的に公開されます。

今、自分のインターフェースを実装したいとしましょう。

public class CustomDataHandler : ICustomData
{
}

これはコンパイル時に壊れ、「CustomData」を実装していないことを教えてくれます

一方、これは機能します。

public class CustomDataHandler : ICustomData
{
    public String CustomData { set; get; }
}

私の質問は次のとおりです。インターフェイスのメンバーが自動的に公開される場合、なぜクラスで実装を宣言する必要があるのですか?インターフェイス宣言が構文的にクラス宣言と同じである場合、コンパイラがインターフェイスからこれを自動的に推測できないのはなぜですか?

編集:

私が尋ねる理由。データモデルやエンティティなどを構築しているシナリオを想像してみてください。これらのモデルへのインターフェイスを次のようにコーディングする場合があります。

public interface IUserAccount
{
    Guid Identity { set; get; }
    String FirstName { set; get; }
    String LastName { set; get; }
    String EmailAddress { set; get; }
    String Password { set; get; }
}

public interface IUserDataEntry
{
    Guid DataIdentity { set; get; }
    String DataName { set; get; }
    String Data { set; get; }
}

次のようにモデルを作成する方がはるかに簡単です。

public class UserAccount : IUserAccount
{
}

public class UserDataEntry : IUserDataEntry
{
}

public class Combined : IUserAccount, IUserDataEntry
{
}
4

6 に答える 6

3

インターフェースは実装を提供するためのものではなく、コントラクトを定義するためのものです。これにより、それを実装するさまざまな実装を構築できます。

于 2012-11-06T09:07:50.523 に答える
2

それらは構文的に同一であるかもしれませんが、それらは異なることを意味します(すなわち、それらは意味的に同一ではありません)。

インターフェイスでは、構文は、実装クラスがそのようなプロパティを公開する必要があることを意味し、getアクセサsetは適切と思われる場合(明示的または暗黙的に)実装されます。インターフェイスは、クラスが提供しなければならない外向きの動作を定義するだけです。その動作の実装は提供されません。

このクラスでは、構文は「auto-property」であり、インターフェースによって定義されたプロパティの実装getであり、およびsetアクセサーは、バッキングフィールドを使用して完全な実装に暗黙的に変換されます。コンパイルすると次のようになります。

public class CustomDataHandler : ICustomData
{
    private string customData;

    public string CustomData
    {
        get
        {
            return customData;
        }
        set
        {
            customData = value;
        }
    }
}
于 2012-11-06T09:08:04.687 に答える
1

暗黙的にインターフェースを実装しています。この場合、クラスのメソッドシグネチャは、インターフェイス(アクセシビリティを含む)のシグネチャと一致する必要があります。メソッドがパブリックとしてマークされていることを確認すると、クラスを見たときに驚きがないことが保証されます。たとえば、次のようになります。

public class CustomDataHandler : ICustomData
{
  String CustomData {get; set}
  String PrivateCustomData {get;set;}
}

両方のプロパティが同じように宣言されている場合でも、CustomDataプロパティは、宣言がPrivateCustomDataの宣言と同じに見えても、インターフェイスで宣言されているためパブリックになります。これは一貫性がなく、コードの保守が難しくなります。

アクセス修飾子を設定したくない場合は、インターフェイスを明示的に実装できます。

public class CustomDataHandler : ICustomData
{
    String ICustomData.CustomData { set; get; }
}
于 2012-11-06T09:06:40.573 に答える
0

インターフェイス宣言は、インターフェイスが定義する動作を指定するだけです。あなたの場合、これはと呼ばれるプロパティであり、タイプCustomDatagetset(読み取り/書き込みプロパティ)がありstringます。

インターフェイスを実装するクラスは、実装を指定するために、まさにそれを実行する必要があります。

ここで、あなたの場合、{ get; set; }インターフェース宣言と同じように見える自動実装プロパティを使用していますが、getメソッドまたはsetメソッドにバッキングフィールドと動作を含めることもできます。

于 2012-11-06T09:08:06.543 に答える
0

明示的に実装する必要があります...そのように実装することに限定されません。フィールドを使用するか、メソッドで他のことを行うことができます。インターフェイスは、このメソッドが存在することを保証するメソッドコントラクトにすぎません。

public class CustomDataHandler : ICustomData
{
    public String CustomData
    {
        get { return "None of your business!"; }
        set { } // Decide to do nothing
    }
}

インターフェイスは、このメソッドが存在することを保証するだけです。あなたがそれでやろうとしていることではありません。

編集:質問の編集に関しては、クラスのコレクションに対してメソッドを1回だけ実装する場合は、インターフェイスではなく親クラスを使用することをお勧めします。ただし、インターフェイスを組み合わせることができますが、親クラスを組み合わせることができません。ただし、クラス階層のさまざまなポイントにインターフェイスを追加できます。

于 2012-11-06T09:09:11.440 に答える
0

CustomDataプロパティがprivate派生クラスにある例を次に示します。

public class CustomDataHandler : ICustomData
{
    private string CustomData { set; get; }

    string ICustomData.CustomData { get; set; }
}

ただし、プロパティの明示的な実装もあるため、このコードはコンパイルされます。

したがって、publicこの場合、修飾子は冗長ではありません。

于 2012-11-06T09:10:47.210 に答える