2010-01-15 14 views
37

मैं RolesService से विरासत में एक नई कक्षा का विस्तार कर रहा हूं। RolesService में मेरे पास एक स्थिर मेथोग है जो मैं अपने नव व्युत्पन्न वर्ग में ओवरराइड करना चाहता हूं। जब मैं अपनी व्युत्पन्न वस्तु से कॉल करता हूं तो यह ओवरराइड स्थैतिक विधि का उपयोग नहीं करता है, जो वास्तव में बेस क्लास विधि को कॉल करता है। कोई विचार?एक स्थिर विधि को ओवरराइड करें

public class RolesService : IRolesService 
{ 
    public static bool IsUserInRole(string username, string rolename) 
    { 
     return Roles.IsUserInRole(username, rolename); 
    } 
} 

public class MockRoleService : RolesService 
{ 
    public new static bool IsUserInRole(string username, string rolename) 
    { 
     return true; 
    } 
} 
+5

मुझे लगता है कि वह समझता है कि आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं। उनका सवाल है "कोई विचार?" उस के आसपास हो रही है। निश्चित नहीं है कि अगर लोग इसका एहसास करते हैं तो सभी उपरोक्त उत्तर देने जा रहे हैं जिसमें हारून के अलावा, इसके आसपास होने के लिए कोई विचार नहीं है। –

उत्तर

18

निम्नलिखित करने से आपको स्थिर कॉल के आसपास काम करने की अनुमति मिल जाएगी। आप कहाँ निर्भरता इंजेक्शन के माध्यम से एक IRolesService ले कोड का उपयोग करना चाहते फिर जब आप MockRolesService जरूरत है आप में पारित कर सकते हैं कि

public interface IRolesService 
{ 
    bool IsUserInRole(string username, string rolename); 
} 

public class RolesService : IRolesService 
{ 
    public bool IsUserInRole(string username, string rolename) 
    { 
     return Roles.IsUserInRole(username, rolename); 
    } 
} 

public class MockRoleService : IRolesService 
{ 
    public bool IsUserInRole(string username, string rolename) 
    { 
     return true; 
    } 
} 
+19

अब 'IsUserInRole' अब एक स्थिर विधि नहीं है। – Gutblender

40

आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं। एक स्थैतिक विधि वर्चुअल नहीं हो सकती है, क्योंकि यह कक्षा के उदाहरण से संबंधित नहीं है।

व्युत्पन्न वर्ग में "ओवर्रिडेन" विधि वास्तव में एक नई विधि है, जो बेस क्लास में परिभाषित एक से संबंधित नहीं है (इसलिए new कीवर्ड)।

18

आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं।

यदि आप इसके बारे में सोचते हैं, तो यह वास्तव में समझ में नहीं आता है; वर्चुअल प्रेषण के लिए आपको किसी ऑब्जेक्ट के वास्तविक जांच की आवश्यकता है।

एक स्थिर विधि भी इंटरफ़ेस को कार्यान्वित नहीं कर सकती है; यदि यह वर्ग IRolesService इंटरफ़ेस को कार्यान्वित कर रहा है तो मैं तर्क दूंगा कि विधि बिल्कुल स्थिर नहीं होनी चाहिए। एक उदाहरण विधि रखने के लिए यह बेहतर डिज़ाइन है, ताकि आप तैयार होने पर अपने MockRoleService को वास्तविक सेवा के साथ स्वैप कर सकें।

12

आप एक स्थिर विधि को ओवरराइड नहीं कर सकते हैं। आपको this एक दिलचस्प पढ़ा जा सकता है।

0

एक स्थैतिक विधि प्रकार के लिए प्रासंगिक तर्क का प्रतिनिधित्व करती है। एक बार जब आप उस प्रकार से प्राप्त हो जाते हैं, तो मूल प्रकार के स्थैतिक तरीकों को लागू करने के लिए नहीं माना जा सकता है। आप क्या कर सकते है निम्नलिखित:

public class RolesService : IRolesService 
{ 
    public static bool IsUserInRole(string username, string rolename) 
    { 
     return Roles.IsUserInRole(username, rolename); 
    } 

    // call this guy within the class 
    protected virtual bool DoIsUserInRole(string username, string rolename) 
    { 
     return IsUserInRole(username, rolename); 
    } 
} 

public class MockRoleService : RolesService 
{ 
    public new static bool IsUserInRole(string username, string rolename) 
    { 
     return true; 
    } 

    protected override bool DoIsUserInRole(string username, string rolename) 
    { 
     return IsUserInRole(username, rolename); // invokes MockRoleService.IsUserInRole 

     // or simply 
     return true; 
    } 
} 
+0

अंतिम विधि में IsUserInRole पर कॉल संदिग्ध है, आपको MockRoleService.IsUserInRole –

+0

पर कॉल करने की आवश्यकता है @ थॉमस सुनिश्चित नहीं हैं कि आपने मेरे संपादन से पहले या बाद में कोड देखा है, लेकिन वर्तमान नमूने में, IsUserInRole पर कॉल MockRoleService.IsUserInRole को आमंत्रित करता है। –

0

आप दो तरह से अपने नकली वस्तु काम कर सकता है कर रहे हैं: (यह मानते हुए IRolesService को RolesService से अपने माता पिता वस्तु के हस्ताक्षर बदलें यदि आप नहीं कर रहे हैं:

1 पहले से इंटरफ़ेस का उपयोग कर)। फिर RolesService के बजाय IRolesService पर नकली कार्यान्वित करें।

public class MockRoleService : IRolesService 
{ 
    public new static bool IsUserInRole(string username, string rolename) 
    { 
     return true; 
    } 
} 
  1. निर्भरता इंजेक्षन भूमिकाओं आपत्ति है।

सार्वजनिक वर्ग MockRoleService: RolesService {

public MockRoleService() 
{ 
    Roles = OverridenRolesObjectThatAlwaysReturnsTrue; 
} 

}

2

आदेश एक स्थिर विधि कॉल करने के लिए, आप प्रकार का प्रत्यक्ष संदर्भ की आवश्यकता होगी:

RolesService.IsUserInRole(...); 

इस मामले में, यदि आप "व्युत्पन्न" वर्ग की स्थिर विधि को सक्षम और कॉल करना चाहते हैं, तो "नया" कीवर्ड छोड़ना आपको अनुमति देगा:

MockRoleService.IsUserInRole(...); 

और अपेक्षित फ़ंक्शन कॉल प्राप्त करें।

मेरा अनुमान है कि यह वह नहीं है जिसे आप ढूंढ रहे हैं। आपके पास पूर्व में आपके कोड में कहीं भी कुछ कॉल है, और आप उम्मीद कर रहे हैं कि एक मॉकिंग टूल बनाने के लिए एक मॉकिंग टूल का उपयोग करके, आप पुराने के स्थान पर इस नए "प्रकार" को इंजेक्शन देंगे।दुर्भाग्य से, यह नहीं है कि यह statics के साथ कैसे काम करता है।

एक मॉकिंग टूल मॉक आउट प्रकार का एक उदाहरण बनाएगा और वास्तविक प्रकार के निर्माण के लिए कॉल के स्थान पर इंजेक्ट करेगा। एक स्थिर विधि के लिए एक कॉल उन सभी को छोड़ देता है।

जैसा कि हारून ने उल्लेख किया है, आपको शायद इस विधि को एक सामान्य उदाहरण विधि बनाना चाहिए। इससे आपकी नियमित सेवा को आपकी नियमित भूमिका सेवा के स्थान पर ठीक से इंजेक्शन दिया जा सकता है, जिससे आप अपने आईआरओएस सेवा इंटरफ़ेस में विधि घोषणा को स्थानांतरित कर सकते हैं और इसे अपने MockRoleService कार्यान्वयन में ओवरराइड कर सकते हैं। फिर, उस कोड में जहां आप RolesService "प्राप्त" करते हैं, तो आप केवल स्थिर के बजाय इंस्टेंस सदस्य को कॉल करते हैं।

IRolesService svc = MyServiceInjector.GetService<IRolesService>(); 
svc.IsUserInRole(...); 
2

क्या कुछ इस तरह के बारे में:।

public interface IRolesService 
{ 
    bool IsUserInRoleImpl(string username, string rolename); 
} 

public abstract class RolesServiceBase<T> where T : IRolesService, new() 
{ 
    protected static T rolesService = new T(); 

    public static bool IsUserInRole(string username, string rolename) 
    { 
     return rolesService.IsUserInRoleImpl(username, rolename); 
    } 
} 

public class RolesService : RolesServiceBase<RolesService>, IRolesService 
{ 
    public bool IsUserInRoleImpl(string username, string rolename) 
    { 
     return Roles.IsUserInRole(username, rolename); 
    } 
} 

public class MockRoleService : RolesServiceBase<MockRoleService>, IRolesService 
{ 
    public bool IsUserInRoleImpl(string username, string rolename) 
    { 
     return true; 
    } 
} 
2

मैं एक ऐसी ही समस्या थी। मैंने विरासत या इंटरफ़ेस का उपयोग नहीं किया, लेकिन बस एक प्रतिनिधि का उपयोग किया।

public class RolesService 
    { 
     static RolesService() 
     { 
      isUserInRoleFunction = IsUserInRole; 
     } 

     public static delegate bool IsUserInRoleFunctionDelegate(string username, string rolename); 

     public static IsUserInRoleFunctionDelegate isUserInRoleFunction { get; set; } 

     private bool IsUserInRole(string username, string rolename) 
     { 
      return Roles.IsUserInRole(username, rolename); 
     } 
    } 

आप परीक्षण प्रयोजनों के लिए विधि "newMethod" बदलना चाहते हैं, बस फोन

RolesService.isUserInRoleFunction = newMethod; 
0

स्थिर मूल्य तक पहुँचने के लिए एक संपत्ति का उपयोग क्यों नहीं? फिर यह विरासत का समर्थन करेगा और अतिसंवेदनशील होगा। जो आप खोज रहे हैं वह प्रतीत होता है।

public class StaticOverride { 
    public virtual string MyVal { get { return MyStaticMethod(); } } 

    public string MyStaticMethod() { 
     return "Example"; 
    } 
} 
संबंधित मुद्दे