2009-04-30 16 views
22

C#コンパイラ:非静的コンテキストで静的メソッドにアクセスできません

私は以下のコードを持っています:

public class Anything 
{ 
    public int Data { get; set;} 
} 

public class MyGenericBase<T> 
{ 
    public void InstanceMethod(T data) 
    { 
     // do some job 
    } 

    public static void StaticMethod(T data) 
    { 
     // do some job 
    } 

    // others members... 
} 

public sealed class UsefulController : MyGenericBase<Anything> 
{ 
    public void ProxyToStaticMethod() 
    { 
     StaticMethod(null); 
    } 

    // others non derived members... 
} 

public class Container 
{ 
    public UsefulController B { get; set; } 
} 

public class Demo 
{ 
    public static void Test() 
    { 
     var c = new Container(); 
     c.B.InstanceMethod(null); // Works as expected. 
     c.B.StaticMethod(null);  // Doesn't work. 
            // Static method call on object rather than type. 
            // How to get the static method on the base type ? 
     c.B.ProxyToStaticMethod(); // Works as expected. 
    } 
} 

コンパイラは非常に怒っています...私はエラーメッセージを理解するが、私はこれを解決する方法を知らない。私は静的メソッド呼び出しを行うためのオブジェクトではなくタイプを取得しようとしていましたが、正しく行う方法は見つかりませんでした。さらに、これはエレガントではない何かの結果をもたらします。

基本的に、GenericBaseは、多くの静的メソッドといくつかのインスタンスメソッドを持つフレームワークのクラスです。コントローラーがこのクラスを入力して拡張しています。

コンテナーは論理的に関連するコントローラーのグループです。

面白いこと:このコードのJavaバージョンは正しくコンパイルされますが、警告が表示されます。実行も正しいです。

これを解決するためのデザインパターンは存在しますか?

あなたの入力をありがとう!


私はあなたの答えのおかげで、この問題を取り除く方法を見つけました。それはうまくいくようですが、私は、副作用が正しいかどうかを知ることはできません。

 public class GenericBase<T> : MyGenericBase<T> 
{ 
    // Create instance calls here for every base static method. 
} 

public sealed class UsefulController : GenericBase<Anything> 
{ 
    // others non derived members... 
} 

答えて

26

静的メソッドの呼び出しは、特定のクラスに対して特定の静的メソッドを呼び出すようにコンパイルされます。つまり、呼び出す静的メソッドを決定するためにBの内容を使用しません。

コールがコンパイル時に解決可能でなければならないので、それはわかっているので、そのプロパティの内容を複数の具体的な型に置き換えることができます。つまり、静的メソッドを呼び出すと、これらのクラスのいずれかで静的メソッドに解決されます。

コンパイラには、仮想または抽象的な静的メソッドのようなものはありません。そのため、これらのクラスにすべてその静的メソッドがあることを保証することはできません。呼び出しはコンパイル時に解決可能でなければならないので、そのようには機能しません。

あなたが気付いたように、オブジェクトのインスタンスメソッドを呼び出すことができます。オブジェクトメソッドは、静的メソッドを呼び出します。これはコンパイラがそのインスタンスメソッドをコンパイルするときに呼び出される静的メソッドが一定で既知であるため、上記の規則を無効にしません。

+0

非常に有益な、ありがとう!以下の答えを読んで、私は可能な解決策について疑問に思います。お気軽にコメントしてください。結局のところ –

+0

、彼らは何のためにもSTATICと呼ばれていません – BlackTigerX

2

C#でこれを行うことはできません。あなたはVB.NETとJavaでそれを行うことができますが、正直なところ、それは実際には意味がありません。 staticメソッドでは、多形性の誤った感覚を提供しますが、これは決して実際的ではありません。ポリモーフィックではないので、メソッド呼び出し全体がコンパイル時(静的)にわかり、クラス名で直接呼び出すことができます。

9

静的メソッドを呼び出すには、そのクラスのインスタンスではなく、定義されているクラスから静的メソッドを参照する必要があります。

MyGenericBase<Anything>.StaticMethod(null); 
+0

ありがとう!私はすでにこれに気づいた。私はコンテナを介してこれらの呼び出しを行う方法を探しています。最初に基本クラスを静的メソッドへのインスタンス呼び出しを含む別の基底に派生させてから派生させると思いますか? –

1

あなたはそれらのいずれかを行うことができます

UsefulController.StaticMethod(null); 
MyGenericBase<Anything>.StaticMethod(null); 

既に他の人が説明したように、インスタンスを使用すると、ことはできません。

+0

ありがとう!私はすでにこれに気づいた。私はコンテナを介してこれらの呼び出しを行う方法を探しています。最初に基本クラスを静的メソッドへのインスタンス呼び出しを含む別の基底に派生させてから派生させると思いますか? –

+0

このインスタンスコールが必要な場合は、プロキシメソッドを追加するだけです。私のアドバイスは、APIをきれいにして明瞭に保つことです。 – Lucero

+0

私は静的メンバーを含むクラスを使って直接呼び出すことはできないので、今のところ唯一の解決策であるようです。私は、APIを可能な限りきれいに保つことに同意します。 –

関連する問題