2008-08-18 19 views
10

में स्टेटिक तरीके पहले बंद, मैं कारणों को समझता हूं कि इंटरफ़ेस या अमूर्त वर्ग (.NET/C# शब्दावली में) में अमूर्त स्थैतिक तरीकों क्यों नहीं हो सकते हैं। मेरा सवाल तब सबसे अच्छा डिजाइन समाधान पर केंद्रित है।इंटरफ़ेस/सार कक्षा

जो मैं चाहता हूं वह "सहायक" वर्गों का एक सेट है, जिसमें सभी की अपनी स्थिर विधियां हैं जैसे कि अगर मुझे किसी तृतीय पक्ष विक्रेता से ऑब्जेक्ट ए, बी और सी मिलती है, तो मेरे पास

जैसी विधियों के साथ सहायक वर्ग हो सकते हैं
 
AHelper.RetrieveByID(string id); 
AHelper.RetrieveByName(string name); 
AHelper.DumpToDatabase(); 

मेरी AHelper, BHelper, और CHelper कक्षाएं सभी मूल रूप से एक ही तरीके का होगा बाद से, यह समझ में आता है के लिए एक इंटरफेस है कि इन कक्षाओं में फिर से प्राप्त करने के लिए इन तरीकों को स्थानांतरित करने लगता है। हालांकि, इन तरीकों को स्थैतिक होने की इच्छा रखने से मुझे उन सभी के लिए एक सामान्य इंटरफेस या अमूर्त वर्ग होने से रोक दिया जाता है।

मैं हमेशा इन तरीकों गैर स्थिर बनाने के लिए और फिर वस्तुओं का दृष्टांत के पहले इस तरह के रूप में

 
AHelper a = new AHelper(); 
a.DumpToDatabase(); 

हालांकि, इस कोड प्रतीत नहीं होता है मेरे लिए सहज हो सकता है। आपके सुझाव क्या हैं? क्या मुझे एक इंटरफ़ेस या अमूर्त वर्ग का उपयोग करके पूरी तरह से छोड़ना चाहिए (जिस स्थिति में मैं अभी हूं) या क्या संभवत: मैं उस डिज़ाइन को पूरा करने के लिए पुनः सक्रिय किया जा सकता हूं जिसे मैं ढूंढ रहा हूं?

उत्तर

3

खोज रहे हैं your response पर मैं निम्नलिखित पंक्तियों के साथ सोच रहा हूं:

  • आपके पास एक स्थिर विधि हो सकती है जो एक प्रकार पैरामीटर लेती है और प्रकार के आधार पर अपेक्षित तर्क निष्पादित करती है।
  • आप अपने सार आधार में वर्चुअल विधि बना सकते हैं, जहां आप कंक्रीट क्लास में SQL निर्दिष्ट करते हैं। इसलिए इसमें उप-वर्गों में "विशेषज्ञ" बिट्स (उदा। एसक्यूएल) को समाहित करते समय दोनों सामान्य कोड शामिल हैं (उदा। कमांड को निष्पादित करना और ऑब्जेक्ट को वापस करना)।

मैं दूसरा विकल्प पसंद करता हूं, हालांकि यह आपके लिए निश्चित रूप से नीचे है। तुम मुझे आगे विस्तार में जाने की जरूरत है, तो कृपया मुझे बताएं और मैं/अद्यतन :)

+0

आईएमएचओ: पहला विकल्प जेनेरिक होने से बेहतर होगा, इसलिए प्रकार का अनुमान लगाया जा सकता है जो कि बेहतर है। –

1

सी # 3.0 में, स्थिर विधियों के नीचे DumpToDatabase() के साथ, इंटरफेस पर इस्तेमाल किया जा सकता रूप में यदि वे विस्तार तरीकों का उपयोग करके उनमें से एक हिस्सा थे के रूप में:

static class HelperMethods 
{ //IHelper h = new HeleperA(); 
    //h.DumpToDatabase() 
    public static void DumpToDatabase(this IHelper helper) { /* ... */ } 

    //IHelper h = a.RetrieveByID(5) 
    public static IHelper RetrieveByID(this ObjectA a, int id) 
    { 
      return new HelperA(a.GetByID(id)); 
    } 

    //Ihelper h = b.RetrieveByID(5)  
    public static IHelper RetrieveByID(this ObjectB b, int id) 
    { 
      return new HelperB(b.GetById(id.ToString())); 
    } 
} 
2

मैं व्यक्तिगत रूप से शायद यही कारण है कि सवाल हैं के प्रत्येक प्रकारों को आगे सोचने से पहले एक स्थिर विधि की आवश्यकता होती है ..

क्यों स्थिर विधियों के साथ एक यूटिलिटी क्लास नहीं बनाते जिसे उन्हें साझा करने की आवश्यकता है? (जैसे ClassHelper.RetrieveByID(string id) या ClassHelper<ClassA>.RetrieveByID(string id)

"बाधाओं" समस्या भाषा की सीमाओं नहीं, लेकिन मेरे डिजाइन की सीमाओं है के इन प्रकार के साथ मेरा अनुभव में ..

2

कैसे ObjectA और AHelper से संबंधित हैं? AHelper.RetrieveByID() है BHelper.RetrieveByID()

हाँ, तो कैसे एक उपयोगिता वर्ग आधारित दृष्टिकोण (वर्ग केवल सार्वजनिक स्थिर तरीकों के साथ और कोई राज्य)

static [return type] Helper.RetrieveByID(ObjectX x) 
0

के बारे में मैं कैसे करूँ रूप में एक ही तर्क स्टैक ओवरफ़्लो पर प्रतिक्रिया पोस्ट करें? मेरी मूल पोस्ट संपादित करें या "उत्तर" पोस्ट करें? वैसे भी, मैंने सोचा कि यह AHelper.RetrieveByID() और BHelper.RetreiveByID()

मूल रूप से, ये दोनों विधियां किसी तृतीय पक्ष webservice के विरुद्ध जा रही हैं जो एक अलग-अलग देता है एक क्वेरी विधि का उपयोग कर जेनेरिक (जाली योग्य) ऑब्जेक्ट जो छद्म-एसक्यूएल स्ट्रिंग में अपने केवल पैरामीटर के रूप में होता है।

तो, AHelper.RetrieveByID (स्ट्रिंग आईडी)

 
public static AObject RetrieveByID(string ID) 
{ 
    QueryResult qr = webservice.query("SELECT Id,Name FROM AObject WHERE Id = '" + ID + "'"); 

    return (AObject)qr.records[0]; 
} 

public static BObject RetrieveByID(string ID) 
{ 
    QueryResult qr = webservice.query("SELECT Id,Name,Company FROM BObject WHERE Id = '" + ID + "'"); 

    return (BObject)qr.records[0]; 
} 

उम्मीद है कि मदद करता है कि कैसा लग सकता है। जैसा कि आप देख सकते हैं, दो विधियां समान हैं, लेकिन क्वेरी वापस आने वाले विभिन्न ऑब्जेक्ट प्रकार के आधार पर काफी अलग हो सकती है।

ओह, और रॉब, मैं पूरी तरह से सहमत हूं - यह संभवतः मेरे डिजाइन की सीमा से अधिक है, न कि भाषा।:)

0

क्या आप पॉलिमॉर्फिक व्यवहार की तलाश में हैं? फिर आप इंटरफेस और सामान्य कन्स्ट्रक्टर चाहते हैं। एक कन्स्ट्रक्टर को कॉल करने के बारे में अनजान क्या है? यदि आपको पॉलीमोर्फिज्म की आवश्यकता नहीं है (जैसे लगता है कि अब आप इसका उपयोग नहीं करते हैं), तो आप अपने स्थिर तरीकों से चिपके रह सकते हैं। यदि ये एक विक्रेता घटक के चारों ओर सभी रैपर हैं, तो हो सकता है कि आप उन्हें फैक्टर विधि का उपयोग करने की कोशिश कर सकें जैसे उन्हें वेंडरबिल्डर। गेटवेंडर टिंगिंग ("ए") जो टाइप IVendorWrapper के ऑब्जेक्ट को वापस कर सकता है।

2

आप केवल वापसी प्रकार को बदलकर विधियों को अधिभारित नहीं कर सकते हैं।

आप अलग अलग नामों का उपयोग कर सकते हैं:

static AObject GetAObject(string id); 
static BObject GetBObject(string id); 

या आप कास्टिंग ऑपरेटरों के साथ एक वर्ग बना सकते हैं:

class AOrBObject 
{ 
    string id; 
    AOrBObject(string id) {this.id = id;} 

    static public AOrBObject RetrieveByID(string id) 
    { 
     return new AOrBObject(id); 
    } 

    public static AObject explicit operator(AOrBObject ab) 
    { 
     return AObjectQuery(ab.id); 
    } 

    public static BObject explicit operator(AOrBObject ab) 
    { 
     return BObjectQuery(ab.id); 
    } 
} 

तो फिर तुम यह इतना की तरह कॉल कर सकते हैं:

var a = (AObject) AOrBObject.RetrieveByID(5); 
var b = (BObject) AOrBObject.RetrieveByID(5); 
3

संपादित करने के लिए अपने उदाहरण के लिए एक क्रियाशील समाधान के लिए खुश हो जाएगा, तो आप ऐसा कर सकते हैं:

public static T RetrieveByID<T>(string ID) 
{ 
    var fieldNames = getFieldNamesBasedOnType(typeof(T)); 
    QueryResult qr = webservice.query("SELECT "+fieldNames + " FROM " 
            + tyepof(T).Name 
            +" WHERE Id = '" + ID + "'"); 
    return (T) qr.records[0]; 
} 
+0

+1।मैं इसे कई पूछताछ libs में करता हूं, विशेष रूप से वे जो वेब सेवाओं के माध्यम से बहते हैं। – jro

5

हैं मैं आप थे मैं किसी भी statics से बचने की कोशिश करेंगे। आईएमएचओ मैं हमेशा सांख्यिकी के साथ सड़क के नीचे कुछ प्रकार के सिंक्रनाइज़ेशन मुद्दों के साथ समाप्त हुआ। ऐसा कहा जा रहा है कि आप टेम्पलेट का उपयोग कर जेनेरिक प्रोग्रामिंग का क्लासिक उदाहरण पेश कर रहे हैं। मैं उपरोक्त पदों में से एक में प्रस्तुत रोब कॉपर के टेम्पलेट आधारित समाधान को अपनाऊंगा।

0

marxidad बस एक त्वरित बिंदु नोट करने के लिए, जस्टिन पहले से ही कहा है कि एसक्यूएल एक बहुत प्रकार पर निर्भर भिन्न होता है, तो मैं आधार पर काम किया है यह कुछ पूरी तरह से, प्रकार पर विभिन्न निर्भर इसलिए सौंपने हो सकता है कि प्रश्न में उपclasses के लिए। जबकि आपका समाधान एसक्यूएल बहुत प्रकार को कसकर जोड़ता है (यानी यह एसक्यूएल है)।

rptony स्टैटिक्स के साथ संभव समन्वयन समस्याओं पर अच्छा बिंदु, एक मैं उल्लेख करने में विफल है, तो धन्यवाद साथ ही, इसके रोब कूपर (नहीं कॉपर) :) BTW;): डी (संपादित करें: बस सोचा था कि मैं उल्लेख होगा कि यदि एक टाइपो नहीं था, तो मुझे उम्मीद है कि यह है, इसलिए कोई समस्या नहीं है!)