0

C#で明示的なインターフェイスの実装を使用している場合、そのインターフェイスのメンバーにアクセスするために、そのインターフェイスの1つにオブジェクトをキャストする必要が生じることがよくあります。コンパイル時の型チェックによって信頼性と保守性が向上したため、これを実行するために暗黙の変換を使用することを常に好みました。これを行うために私が知っている唯一の方法は、2行のコードを含み、スコープに別の変数を導入します。以下に例を示します。

public interface IMyType
{
    string SayHello();
}

public class MyType : IMyType
{
    string IMyType.SayHello() { return "Hello!"; }
}

class Program
{
    static void Main(string[] args)
    {
        var item = new MyType();

        // Option 1 - Implicit cast. Compile time checked but takes two lines.
        IMyType item2 = item;
        System.Console.WriteLine(item2.SayHello());

        // Option 2 - One line but risks an InvalidCastException at runtime if MyType changes.
        System.Console.WriteLine(((IMyType)item).SayHello());

        // Option 3 - One line but risks a NullReferenceException at runtime if MyType changes.
        System.Console.WriteLine((item as IMyType).SayHello());
    }
}

コンパイラはその実装を知っているので、後で宣言を変更すると実行時ではなくコンパイルエラーが発生するため、暗黙的なキャストの方が明示的なキャストよりも優れていると思います。ただし、明示的なキャスト構文の単純さをいくらか好み、他の人のコードで使用されるのをよく見ました。MyTypeIMyTypeMyTypeInvalidCastException

私の質問は3つあります:

  • 上記のオプションのどれが好きですか(そしてその理由)?
  • これを行うためのより良い方法はありますか?
  • 暗黙的なキャストが可能な場合に明示的なキャストを実行することに関するいくつかのベストプラクティスは何ですか?
4

4 に答える 4

2

コンパイル時にチェックされた1つのライナーは次のとおりです。

public static class Converter
{
    public static T ReturnAs<T>(T item)
    {
        return item;
    }
}


class Program
{
    static void Main(string[] args)
    {
        var item = new MyType();

        // Option 1 - Implicit cast. Compile time checked but takes two lines.
        IMyType item2 = item;
        System.Console.WriteLine(item2.SayHello());

        // Option 2 - One line but risks an InvalidCastException at runtime if MyType changes.
        System.Console.WriteLine(((IMyType)item).SayHello());

        // Option 3 - One line but risks a NullReferenceException at runtime if MyType changes.
        System.Console.WriteLine((item as IMyType).SayHello());

        // Option 4 - compile time one liner
        Converter.ReturnAs<IMyType>(item).SayHello();
    }
}
于 2010-05-20T19:57:44.093 に答える
1

3つの質問すべてに対する答えとして:原則として暗黙のキャストに依存します。実装ではなく、インターフェースに対してプログラミングしているのです。

最後の1つについては、実装(特定の派生クラス)に対するプログラミングに本当に依存する必要がある場合は、オブジェクトを使用して何かを実行する前に、オブジェクトが型をキャストできることを確認してください。このようなもの:

var IMyType item3 = item as MyConcreteType;
if(item3 != null) {
    item3.SayHello();
}
于 2010-05-20T18:09:32.340 に答える
0

オブジェクトがインターフェイスのインスタンスであるかどうかわからない場合は、as/nullチェックを実行してください。通常、メソッド/関数呼び出しからインターフェイスを返します。この場合、キャストなしで変数に格納するだけです(ただし、nullチェックが必要な場合もあります)。

于 2010-05-20T19:52:59.420 に答える
-1

私は通常それが好きです:

class Program
{
    static void Main(string[] args)
    {
        var item = new MyType();
        if( item is IMyType ){
          Console.WriteLine( (item as IMyType).SayHello() );
        }
        else { /* Do something here... */ }

     }
}
于 2010-05-20T18:12:16.253 に答える