web-dev-qa-db-ja.com

ダイナミックの使用は悪い習慣と見なされますか?

C#では、次のことができます。

MyClass myInstance        = new MyClass();
dynamic mydynamicInstance = myInstance;

次に、次のようなメソッドを呼び出します。

//This method takes a MyClass argument and does something.
Caller.InvokeMethod(myDynamicInstance);

これにより、実行時にmyInstanceタイプが決定され、有効な場合はCaller.InvokeMethodは通常どおり呼び出されます。

さて、私の質問は、これがdynamicを使用することを悪い習慣と見なすかどうか、特に以下の場合です:

1)InvokeMethodは、内部のリフレクションを使用して、myDynamicInstanceタイプの別のインスタンスをインスタンス化します。

2)抽象基本クラスMyBaseClassと、MyBaseClassを含むそのサブクラスがいくつかあります。これらのすべての派生クラスにInvokeMethodのオーバーロードメソッドが多数ある場合、実行時に型の決定を可能にし、メソッドのオーバーロード(または呼び出しのレイトバインディングによる適切な呼び出し)を許可するために使用できますそのクラスのメソッドの)?:

public abstract class MyBaseClass         {/*...*/}
public class MyClass        : MyBaseClass {/*...*/}
public class MyAnotherClass : MyBaseClass {/*...*/}

MyBaseClass myBaseClassRef = new MyClass();
dynamic myDynamicInstance  = myBaseClassRef;

Caller.InvokeMethod(myDynamicInstance);
39

Fabienがあなたに追加の利益をもたらさないことに完全に同意しません。彼が訪問者パターンで解決しているものはMultiple dispatchと呼ばれ、dynamicはこれに対してもき​​れいな解決策を提供できます。ファビアンが言及したパフォーマンス、静的型チェックなどの意味を知っておく必要があります...

public abstract class MyBaseClass
{
}

public class MyClass : MyBaseClass
{
}
public class MyAnotherClass : MyBaseClass
{
}

public class ClassThatIsUsingBaseClass
{
    public static void PrintName(MyBaseClass baseClass)
    {
        Console.WriteLine("MyBaseClass");
    }

    public static void PrintName(MyClass baseClass)
    {
        Console.WriteLine("MyClass");
    }

    public static void PrintName(MyAnotherClass baseClass)
    {
        Console.WriteLine("MyAnotherClass");
    }

    public static void PrintNameMultiDispatch(MyBaseClass baseClass)
    {
        ClassThatIsUsingBaseClass.PrintName((dynamic)baseClass);
    }
}

そして使用法は

static void Main(string[] args)
{
    MyBaseClass myClass = new MyClass();
    MyBaseClass myAnotherClass = new MyAnotherClass();
    ClassThatIsUsingBaseClass.PrintName(myClass);
    ClassThatIsUsingBaseClass.PrintName(myAnotherClass);
    ClassThatIsUsingBaseClass.PrintNameMultiDispatch(myClass);
    ClassThatIsUsingBaseClass.PrintNameMultiDispatch(myAnotherClass);

    Console.ReadLine();
}

出力は

MyBaseClass
MyBaseClass
MyClass
MyAnotherClass

詳細については、「Multiple dispatch」および「C#multiple dispatch」を検索してください。

5
Muraad Nofal