2009-04-18 14 views
12

स्टेटिक विरासत उदाहरण विरासत की तरह काम करता है। सिवाय इसके कि आपको स्थैतिक तरीकों को वर्चुअल या अमूर्त बनाने की अनुमति नहीं है।सी # आभासी (या अमूर्त) स्थैतिक विधियां

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

संभावित डुप्लिकेट [क्यों मैं सी # में सार स्थिर विधियों नहीं कर सकता?] (Https://stackoverflow.com/questions/3284/why-cant-i-have-abstract-static-methods-in-c) –

उत्तर

12

नहीं, आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं। "स्थैतिक" का अर्थ यह भी है कि यह स्थिर रूप से संकलक द्वारा बाध्य है, इसलिए वास्तविक विधि को कॉलटाइम पर नहीं मिला है, लेकिन संकलन समय पर बाध्य है।

आपको क्या करना चाहिए कक्षा को गैर-स्थैतिक बनाना है। विधि वर्चुअल बनाएं और इसे ओवरराइड करें और वास्तविक विरासत का पूर्ण लाभ बनाएं। फिर, यदि आपको वास्तव में इसकी आवश्यकता है, तो अपनी कक्षा के संदर्भ में एक स्थिर प्रविष्टि बिंदु बनाएं। उदाहरण के लिए एक स्थिर कारखाना, सिंगलटन (यह ज्यादातर मामलों में एक विरोधी पैटर्न है लेकिन एक स्थिर वर्ग के रूप में अच्छा है) या सिर्फ एक स्थिर संपत्ति है।

8

आप एक प्रतिनिधि, जरूरत के रूप में जो एक उपवर्ग को बदल सकता है के रूप में TargetMethod संग्रहीत कर सकती है: - _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"); 
     }); 
    } 
} 

इन के बाद से स्थिर उदाहरणों, हालांकि रहे हैं 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

यहाँ ठीक है मैं

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; 
    } 
} 

क्या किया है मुझे लगता है कि यह है कि क्या आप भी कई शुद्धतावादी OO सिद्धांतों को तोड़ने के बिना क्या करना चाहते हैं के लिए एक व्यवहार्य समाधान हो जाएगा।

संबंधित मुद्दे