2010-01-13 10 views
6

क्या classmethod पाइथन में सी # में क्या करने का कोई तरीका है?सी # के लिए पायथन-शैली वर्ग विधि?

यही एक स्थिर कार्य है जिसे टाइप ऑब्जेक्ट को एक (अंतर्निहित) पैरामीटर के रूप में प्राप्त किया जाएगा, जो भी उप-वर्ग का उपयोग किया जाता है।

जो मैं चाहता का एक उदाहरण है, लगभग,

class Base: 
    @classmethod 
    def get(cls, id): 
     print "Would instantiate a new %r with ID %d."%(cls, id) 

class Puppy(Base): 
    pass 

class Kitten(Base): 
    pass 

p = Puppy.get(1) 
k = Kitten.get(1) 

उम्मीद उत्पादन

Would instantiate a new <class __main__.Puppy at 0x403533ec> with ID 1. 
Would instantiate a new <class __main__.Kitten at 0x4035341c> with ID 1. 

(same code on codepad here.)

उत्तर

1

सिद्धांत रूप में, आप कुछ इस तरह लिख सकते हैं। या, यदि आप मस्तिष्कवादी महसूस कर रहे थे, तो आप Puppy.Get<Puppy>(10) या यहां तक ​​कि Kitty.Get<Puppy> लिख सकते हैं;) सभी मामलों में, आपको स्पष्ट रूप से इस प्रकार के प्रकार को स्पष्ट रूप से पास करना होगा।

वैकल्पिक रूप से, यह भी काम करता है:

class Base<T> where T : Base<T>, new() 
{ 
    public static T Get(int id) 
    { 
     return new T() { ID = id }; 
    } 

    public int ID { get; set; } 
} 

class Puppy : Base<Puppy> 
{ 
} 

class Kitten : Base<Kitten> 
{ 
} 

तुम अब भी वापस आधार वर्ग है, जो आप Puppy.Get(10) लिखने के रूप में उम्मीद की अनुमति देता है अप करने के लिए प्रकार पारित करने के लिए की जरूरत है।

लेकिन फिर भी, क्या ऐसा लिखने का कोई कारण है जब var p = new Puppy(10) उतना ही संक्षिप्त और अधिक मूर्खतापूर्ण है? शायद ऩही।

2

संदर्भ के आधार पर, आप या तो जेनरिक या आभासी तरीकों चाहते हैं।

class Base 
{ 
    public static T Get<T>(int id) 
     where T : Base, new() 
    { 
     return new T() { ID = id }; 
    } 

    public int ID { get; set; } 
} 

तो फिर तुम var p = Base.Get<Puppy>(10) लिख सकते हैं:

0

यह ऑब्जेक्ट पास्कल में कक्षा विधियों के बराबर है। (एक .NET कार्यान्वयन RemObject ऑक्सीजन होगा)।

हालांकि, कक्षा संदर्भ और इस प्रकार वर्चुअल क्लास विधियों या प्रतीत होता है कि स्थिर वर्ग जो कुछ वर्ग-स्तरीय राज्य तक पहुंच सकते हैं, वहां मूल मंच में अच्छा है, मुझे नहीं लगता कि वे .Net या C# के लिए अधिक समझदारी करते हैं।

मैं कई वर्षों तक ऑक्सीजन में भी प्रोग्राम करता था, और मुझे कक्षा संदर्भों की आवश्यकता नहीं थी।

ऐसा नहीं है क्योंकि मुझे नहीं पता था कि उनका उपयोग कैसे किया जाए। "मूल" ऑब्जेक्ट पास्कल प्लेटफ़ॉर्म, मूल डेल्फी में, मैंने उन्हें सभी का उपयोग किया था। लेकिन क्योंकि नेट और बीसीएल के लिए उनके लिए कोई वास्तविक समर्थन नहीं है, इसलिए आपके पास उनका उपयोग करके कोई लाभ नहीं है। जबकि पाइथन या देशी डेल्फी जैसे प्लेटफॉर्म उनके पुस्तकालयों में उनका समर्थन करते हैं।

आप स्पष्ट रूप से एक स्थैतिक विधि नहीं चाहते हैं, जो आप चाहते हैं वह राज्य है और/या विरासत का समर्थन कर सकता है। तो या तो कारखानों, या आपके मामले में एक कन्स्ट्रक्टर भी ठीक हो सकता है।

0

क्योंकि सी # स्थिर रूप से संकलित है, Puppy.get() पर कॉल संकलन समय पर हल किया गया है, उदाहरण के लिए। यह Base.get() को इंगित करने में जाना जाता है और इसका मतलब है कि उत्पन्न सीआईएल (आम मध्यवर्ती भाषा) Base.get() के लिए एक कॉल अनुदेश होगा:

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    // Code size  9 (0x9) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldc.i4.1 
    IL_0002: call  void Base::get(int32) 
    IL_0007: nop 
    IL_0008: ret 
} 
संबंधित मुद्दे