web-dev-qa-db-ja.com

同じ名前の静的メソッドとインスタンスメソッド?

C#に静的インターフェイスと非静的インターフェイスの両方を持つクラスがあります。同じ名前とシグネチャを持つクラスに静的メソッドと非静的メソッドを含めることは可能ですか?

これを実行しようとするとコンパイラエラーが発生しますが、何らかの理由でこれを実行する方法があると思いました。私は間違っていますか、同じクラスに静的メソッドと非静的メソッドの両方を含める方法はありませんか?

これが不可能な場合、一般的にあらゆる状況に適用できるこのようなものを実装する良い方法はありますか?

[〜#〜]編集[〜#〜]
受け取った回答から、これを行う方法がないことは明らかです。この問題を回避するには、別の命名システムを使用します。

52
Dan Herbert

いいえ、できません。制限の理由は、クラス名を前に付ける必要なしに、静的メソッドを非静的コンテキストから呼び出すこともできるためです(つまり、MyClass.MyStaticMethod()ではなくMyStaticMethod())。コンパイラーは、両方がある場合、どちらを探しているのか判別できません。

同じ名前の静的メソッドと非静的メソッドを使用できますが、メソッドのオーバーロードと同じルールに従う異なるパラメーターを使用できます。これらはまったく同じシグネチャを持つことはできません。

58
ckramer

実際には、インターフェイスを明示的に実装することでこれを実現する方法があります。これは完璧なソリューションではありませんが、場合によっては機能します。

interface IFoo
{
    void Bar();
}

class Foo : IFoo
{
    static void Bar()
    {
    }

    void IFoo.Bar()
    {
        Bar();
    }
}

P/Invoke呼び出しのラッパークラスを作成すると、この状況に遭遇することがあります。

47
andasa

タイプ名を指定しなくても、インスタンスメソッドから静的メソッドを呼び出すことができます。

class Foo
{
    static void Bar()
    {
    }

    void Fizz()
    {
        Bar();
    }
}

...つまり、同じシグネチャを持つ静的メソッドとインスタンスメソッドを持つことは許可されないのは当然です。

あなたは何を成し遂げようとしているのですか?詳細を知らずに回避策を提案するのは困難です。いずれかのメソッドの名前を変更します。

12
Matt Hamilton

これに関してはC#はうまく設計されていません...

グローバルまたは非グローバルが必要になる可能性があることは事実ですが、デフォルトで1つを選択する必要があります。もう1つが必要な場合は、単にそれをさらに修飾します。

class Logger {
   public static Logger instance;

   public static void Log(string message) {
       instance.Log(message); // currently the compiler thinks this is ambiguous, but really its not at all.  Clearly we want the non-static method
   }

   public void Log(string message) {

   }

   public void DoStuff() {
      Log("doing instance stuff"); // this could be ambiguous, but in my opinion it should default to a call to this.Log()
      Logger.Log("doing global stuff"); // if you want the global qualify it explicitly
   }
}
3
Nick Sotiros

OK。この問題の原因は、C#では型名を指定せずにインスタンスメソッドから静的メソッドを呼び出せないことです。

他の完全なOO言語(Smalltalkなど)はこれを許可していません。また、オブジェクトを理解する人々を混乱させるだけです。インスタンス側とクラス(または静的)側の分離は非常に重要であり、これらの詳細で混乱を助長する言語は........良い考えではありません...しかし、MSに期待される典型的なタイプのものです。

エイドリアン

0
Adrian

宣言とパラメーターの数が異なる限り、同じ名前の静的メソッドとインスタンスメソッドを使用できます。クラス内に同じ名前の2つのインスタンスメソッドを作成する方法は同じです。

技術的には、静的メソッドとインスタンスメソッドの場合は、インスタンスメソッドに暗黙のthisパラメーターが存在することですでに異なりますが、その違いは、コンパイラーが2つのうちどちらを呼び出すかを決定するには十分ではありません。

更新:間違えました。戻り値は、異なる署名を持つには不十分です。

0
Franci Penov