2009-04-18 14 views
12

静的継承は、インスタンス継承と同じように機能します。静的メソッドを仮想または抽象的にすることは許されません。C#仮想(または抽象)静的メソッド

class Program { 
    static void Main(string[] args) { 
     TestBase.TargetMethod(); 
     TestChild.TargetMethod(); 
     TestBase.Operation(); 
     TestChild.Operation(); 
    } 
} 

class TestBase { 
    public static void TargetMethod() { 
     Console.WriteLine("Base class"); 
    } 

    public static void Operation() { 
     TargetMethod(); 
    } 
} 

class TestChild : TestBase { 
    public static new void TargetMethod() { 
     Console.WriteLine("Child class"); 
    } 
} 

この意志出力:

Base class 
Child class 
Base class 
Base class 

しかし、私が欲しい:

Base class 
Child class 
Base class 
Child class 

それは、私は静的メソッドで、私はTargetMethodが仮想なるだろう可能性があり、それが仕事をしたい場合。しかし、同じ効果を得るための回避策がありますか?

編集:はい、私は、子クラスにオペレーションのコピーを置くことができますが、これは私の場合は約35クラス、メンテナンスの悪夢であるすべての子供に大量のコードをコピーして貼り付ける必要があります。

+0

なぜ静的関数を使用していますか? – munificent

+0

継承をルックアップと名前の隠蔽と混同しています。 –

+0

[C#で抽象静的メソッドを使用できないのはなぜですか?](https://stackoverflow.com/questions/3284/why-cant-i-have-abstract-static-methods-in-c) –

答えて

12

いいえ、静的メソッドを上書きすることはできません。 「静的」とは、コンパイラによって静的にバインドされていることを意味します。したがって、呼び出される実際のメソッドは実行時には検出されず、コンパイル時にはバインドされます。

クラスを非静的にする必要があります。メソッドを仮想にして、それをオーバーライドし、実際の継承を最大限に活用します。次に、本当に必要な場合は、クラスの参照への静的エントリポイントを作成します。たとえば、スタティックファクトリ、シングルトン(大部分のケースではアンチパターンですが、静的クラスほど良いパターンです)または静的プロパティです。

8

必要に応じて、サブクラスは変更可能性がある、デリゲートとしてTargetMethodを格納することができ:

class TestBase { 
    protected static Action _targetMethod; 

    static new() { 
     _targetMethod = new Action(() => { 
      Console.WriteLine("Base class"); 
     }); 
    } 

    public static void TargetMethod() { 
     _targetMethod(); 
    } 

    public static void Operation() { 
     TargetMethod(); 
    } 
} 

class TestChild : TestBase { 
    static new() { 
     _targetMethod = new Action(() => { 
      Console.WriteLine("Child class"); 
     }); 
    } 
} 

これらは静的インスタンスですので、しかし - _targetMethodは、すべてのインスタンス間で共有される - TestChildでそれを変更すると、それを変更しますTestBaseについても同様である。あなたはそれを気にするかもしれません。そうした場合は、ジェネリックスやDictionary<Type, Action>が役に立ちます。

しかし、全体的には、静的を主張していない場合や、継承の代わりに合成を使用した方がずっと簡単です。

2

あなたは抽象的な静的メソッドを実行するために探している場合は、この作品、と私はに適応するための最も簡単な解決策であることが判明:

class TestBase<ChildType> where ChildType : TestBase<ChildType> { 
    //public static abstract void TargetMethod(); 

    public static void Operation() { 
     typeof(ChildType).GetMethod("TargetMethod").Invoke(null, null); 
    } 
} 

class TestChild : TestBase<TestChild> { 
    public static void TargetMethod() { 
     Console.WriteLine("Child class"); 
    } 
} 

しかし、使用しているので、私はまだ解決策としてStafanをマーキングしていますインスタンスの継承はおそらく同様の状況にある誰にとっても最高の勧告です。しかし、あまりにも多くのコードを書き直す必要があります。ここ

2

[OK]を、私は、これはあなたがあまりにも多くの純粋主義者のOOの原則を壊すことなく、やりたいことのために実行可能な解決策になると思う私は

public abstract class Base<T> 
    where T : Base<T>, new() 
{ 
    #region Singleton Instance 
    //This is to mimic static implementation of non instance specific methods 
    private static object lockobj = new Object(); 
    private static T _Instance; 
    public static T Instance 
    { 
     get 
     { 
      if (_Instance == null) 
      { 
       lock (lockobj) 
       { 
        if (_Instance == null) 
        { 
         _Instance = new T(); 
        } 

       } 
      } 
      return _Instance; 
     } 
    } 

    #endregion //Singleton Instance 

    #region Abstract Definitions 

    public abstract T GetByID(long id); 
    public abstract T Fill(SqlDataReader sr); 

    #endregion //Abstract Definitions 
} 

public class InstanceClass : Base<InstanceClass> 
{ 
    //empty constructor to ensure you just get the method definitions without any 
    //additional code executing 
    public InstanceClass() { } 


    #region Base Methods 

    public override InstanceClass GetByID(long id) 
    { 
     SqlDataReader sr = DA.GetData("select * from table"); 
     return InstanceClass.Instance.Fill(sr); 
    } 

    internal override InstanceClass Fill(SqlDataReader sr) 
    { 
     InstanceClass returnVal = new InstanceClass(); 
     returnVal.property = sr["column1"]; 
     return returnVal; 
    } 
} 

を行っているものです。

関連する問題