सवाल मैं वर्चुअल और स्थैतिक सी # विधियों की घोषणा क्यों नहीं कर सकता?


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

क्या इसके आसपास कोई रास्ता है? मुझे लगता है कि मैं एक सिंगलटन का उपयोग कर सकता हूं .. HelperClass.Instance.HelperMethod () HelperClass.HelperMethod () से बहुत खराब नहीं है। ब्राउनी किसी भी व्यक्ति के लिए इंगित करता है जो वर्चुअल स्थिर तरीकों का समर्थन करने वाली कुछ भाषाओं को इंगित कर सकता है।

संपादित करें: ठीक है हाँ मैं पागल हूँ। Google खोज परिणामों ने मुझे सोचा था कि मैं थोड़ी देर के लिए नहीं था।


44
2017-10-29 20:17


मूल


इस तरह के परिदृश्य का मतलब है कि आपको इसे वस्तुओं में बदलना चाहिए (सिंगलेट नहीं)। - yfeldblum
मैं हर जगह किसी ऑब्जेक्ट को तुरंत चालू नहीं करना चाहता हूं, हालांकि इस सहायक विधि का उपयोग किया जाता है। - Luke
फिर एक सिंगलटन, या निर्भरता इंजेक्शन का उपयोग करें, जिस पर निर्भर करता है। - Chris Marasti-Georg
के संभावित डुप्लिकेट मैं सी # में अमूर्त स्थैतिक तरीकों क्यों नहीं कर सकता? - Ken Kin
के संभावित डुप्लिकेट वर्चुअल स्थिर गुणों को कैसे कार्यान्वित करें? - peterh


जवाब:


आभासी स्थैतिक तरीकों को समझ में नहीं आता है। अगर मैं फोन करता हूँ HelperClass.HelperMethod();, मैं कुछ यादृच्छिक सबक्लास 'विधि को क्यों कॉल करने की उम्मीद करूंगा? जब आपके पास 2 उप-वर्ग होते हैं तो समाधान वास्तव में टूट जाता है HelperClass - आप किस का उपयोग करेंगे?

यदि आप ओवरराइड करने योग्य स्थैतिक-प्रकार विधियों को रखना चाहते हैं तो आपको शायद इसके साथ जाना चाहिए:

  • एक सिंगलटन, यदि आप एक ही सबक्लास को विश्व स्तर पर इस्तेमाल करना चाहते हैं।
  • एक कारखाने या निर्भरता इंजेक्शन के साथ एक परंपरा वर्ग पदानुक्रम, यदि आप अपने आवेदन के विभिन्न हिस्सों में अलग व्यवहार चाहते हैं।

अपनी स्थिति में जो भी समाधान अधिक समझ में आता है चुनें।


43
2017-10-29 20:21



-1 क्योंकि आप जेनेरिक के बारे में भूल गए हैं। टी। जोड़ें (बाएं टी, दाएं टी); बहुत समझ है। यही है ना - SeeR
और आप उपखंड में अपने कार्यान्वयन को कैसे ओवरराइड करेंगे? - Chris Marasti-Georg
इसे कक्षा के प्रकार के वर्चुअल इंस्टेंस सदस्य के रूप में कार्यान्वित किया जा सकता है। सबक्लास के प्रकार वर्ग के प्रकार से प्राप्त होंगे, जिससे उन्हें ओवरराइड करने की अनुमति मिल जाएगी। - Craig Gidney
हां, लेकिन सबक्लास 'कार्यान्वयन मूल प्रकार से एक स्थिर संदर्भ में उपलब्ध नहीं होगा, जो मूल प्रश्न पूछा गया है। - Chris Marasti-Georg
हां, वे समझ में आते हैं, यह सिर्फ अर्थशास्त्र का मामला है। मैं तर्क दूंगा कि यदि कक्षा के भीतर एक स्थैतिक विधि घोषित करना समझ में आता है, तो यह प्रति-प्रकार के आधार पर इसे ओवरराइड करने की अनुमति देता है। इस धागे में डेल्फी उदाहरण देखें। आप तर्क दे सकते हैं कि 'स्थैतिक' का परिभाषित अर्थ है; ठीक है, सी में इसका सी # और जावा से बहुत अलग अर्थ है, उदाहरण के लिए। - etrusco


मुझे नहीं लगता कि तुम पागल हो। आप बस .NET में वर्तमान में असंभव क्या उपयोग करना चाहते हैं।

यदि हम जेनेरिक के बारे में बात कर रहे हैं तो वर्चुअल स्टेटिक विधि के लिए आपका अनुरोध इतना समझदार होगा। उदाहरण के लिए सीएलआर डिजाइनरों के लिए मेरा भविष्य अनुरोध मुझे इस तरह के intereface लिखने की अनुमति है:

public interface ISumable<T>
{
  static T Add(T left, T right);
}

और इस तरह इसका इस्तेमाल करें:

public T Aggregate<T>(T left, T right) where T : ISumable<T>
{
  return T.Add(left, right);
}

लेकिन अभी यह असंभव है, इसलिए मैं इसे इस तरह कर रहा हूं:

    public static class Static<T> where T : new()
    {
      public static T Value = new T();
    }

    public interface ISumable<T>
    {
      T Add(T left, T right);
    }

    public T Aggregate<T>(T left, T right) where T : ISumable<T>, new()
    {
      return Static<T>.Value.Add(left, right);
    }

29
2018-03-10 23:31



@ सीईआर: -1: अगर मैं गलत हूं, तो मैं इसे सही कर दूंगा, लेकिन यह मूल समस्या को हल नहीं करता है। - John Saunders
@ जॉन सॉंडर्स: वह स्थिर वर्चुअल विधियों को चाहते हैं, लेकिन यह असंभव है - उन्हें इसके लिए इंस्टेंस विधियों का उपयोग करना होगा। वह हर बार इस स्थिर (अब उदाहरण) विधियों का उपयोग करना चाहते हैं, इस कक्षा को तुरंत चालू नहीं करना चाहते हैं - यही कारण है कि मैंने स्टेटिक <टी> कक्षा बनाई। अब पूरे आवेदन के लिए उसके पास केवल अपनी कक्षा का एक उदाहरण होगा। मुझे लगता है कि यह ऐसी कार्यक्षमता के लिए स्वीकार्य कर है। कुल <टी> विधि सिर्फ एक उदाहरण है कि वह इसका उपयोग कैसे कर सकता है। तो संक्षेप में हमारे पास सी # में स्थिर वर्चुअल प्रतिस्थापन है - क्या यह सवाल में अनुरोध नहीं था? - SeeR
@ सीईआर: यदि आपका प्रश्न प्रश्न संतुष्ट करता है तो आपका दृष्टिकोण ठीक काम करता है new बाधा। स्टेटिक वर्चुअल विधियां इस तरह की संरचनाओं को प्रकार-सुरक्षित फैशन में उन प्रकारों के साथ उपयोग करने की अनुमति देती हैं जो संतुष्ट नहीं होतीं new बाधा। वैकल्पिक रूप से, एक हो सकता है Static कक्षा में नहीं है new बाधा, बल्कि एक विशेष पैरामीटरयुक्त कन्स्ट्रक्टर के साथ एक वस्तु बनाने के लिए प्रतिबिंब का उपयोग करने का प्रयास करें। दुर्भाग्यवश, मुझे उस प्रकार-सुरक्षित बनाने का कोई तरीका नहीं पता है। - supercat


दरअसल, यह डेल्फी में किया जा सकता है। एक उदाहरण:

type
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
  end;

  TTestClass = class
  public
    class procedure TestMethod(); virtual;
  end;

  TTestDerivedClass = class(TTestClass)
  public
    class procedure TestMethod(); override;
  end;

  TTestMetaClass = class of TTestClass;

var
  Form1: TForm1;

implementation

{$R *.dfm}

class procedure TTestClass.TestMethod();
begin
  Application.MessageBox('base', 'Message');
end;

class procedure TTestDerivedClass.TestMethod();
begin
  Application.MessageBox('descendant', 'Message');
end;


procedure TForm1.FormShow(Sender: TObject);
var
  sample: TTestMetaClass;
begin
  sample := TTestClass;
  sample.TestMethod;
  sample := TTestDerivedClass;
  sample.TestMethod;
end;

काफी दिलचस्प। मैं अब डेल्फी का उपयोग नहीं करता, लेकिन मुझे मेटाक्लास सुविधा का उपयोग कर एक कस्टम डिजाइनर कैनवास पर विभिन्न प्रकार के नियंत्रण आसानी से बनाने में सक्षम होने की याद आती है: नियंत्रण वर्ग, उदाहरण के लिए। टीबटन, टीटेक्स्टबॉक्स आदि एक पैरामीटर था, और मैं वास्तविक मेटाक्लास तर्क का उपयोग कर उचित कन्स्ट्रक्टर को कॉल कर सकता था।

गरीब आदमी के फैक्ट्री पैटर्न की तरह :)


13
2017-10-29 20:46



तथ्य यह है कि सी # स्थिर आभासी तरीकों का समर्थन नहीं करता है मुझे पागल बनाता है ... विशेष रूप से माना जाता है कि सी # को उसी व्यक्ति द्वारा डिजाइन किया गया है जिसने 10 साल पहले डेल्फी डिजाइन किया था (एंडर्स हेजल्सबर्ग) - Carlo Sirna


आप एक नियमित स्थिर विधि के साथ एक ही प्रभाव प्राप्त कर सकते हैं और उसके बाद इसे छाया कर सकते हैं new कीवर्ड

public class Base 
{
    //Other stuff

    public static void DoSomething()
    {
        Console.WriteLine("Base");
    }
}

public class SomeClass : Base
{
    public new static void DoSomething()
    {
        Console.WriteLine("SomeClass");
    }
}
public class SomeOtherClass : Base
{
}

फिर आप इस तरह के तरीकों को कॉल कर सकते हैं

Base.DoSomething(); //Base
SomeClass.DoSomething(); //SomeClass
SomeOtherClass.DoSomething(); //Base

11
2017-08-22 20:00



इसमें अनपेक्षित परिणाम हो सकते हैं। उदाहरण के लिए, यदि आपकी बेस क्लास में आपके पास एक और तरीका है जो DoSomething को कॉल करता है, और आप SomeClass.ThatOtherMethod () को कॉल करते हैं, तो वह विधि आधार के DoSomething को कॉल करती है, न कि कुछ क्लास के संस्करण। dotnetfiddle.net/scRWKD - user420667
यह सुनिश्चित करने के लिए कि कुछ भी इसे कॉल नहीं करता है, बेस क्लास में NotImplementedException को फेंक दें - Rob Sedgwick


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

    class Root {
       public static virtual string TestMethod() {return "Root"; }
    }
    TRootClass = class of TRoot; // Here is the typed type declaration

    class Derived : Root {
       public static overide string TestMethod(){ return "derived"; }
    }

   class Test {
        public static string Run(){
           TRootClass rc;
           rc = Root;
           Test(rc);
           rc = Derived();
           Test(rc);
        }
        public static Test(TRootClass AClass){
           string str = AClass.TestMethod();
           Console.WriteLine(str);
        }
    } 

उत्पादन करेगा:   जड़   निकाली गई


8
2017-07-06 18:00





एक वर्ग के उदाहरण के बाहर एक स्थिर विधि मौजूद है। यह किसी गैर-स्थैतिक डेटा का उपयोग नहीं कर सकता है।

एक वर्चुअल विधि को ओवरलोडेड फ़ंक्शन द्वारा "अधिलेखित" किया जाएगा प्रकार एक उदाहरण के।

इसलिए आपके पास स्थैतिक और आभासी के बीच एक स्पष्ट विरोधाभास है।

यह समर्थन की समस्या नहीं है, यह एक अवधारणा है।

अद्यतन करें: मैं यहां गलत साबित हुआ (टिप्पणियां देखें):

तो मुझे संदेह है कि आपको कोई ओओपी-भाषा मिलेगी जो वर्चुअल का समर्थन करेगी   स्थैतिक तरीकों।


7
2017-10-29 20:21



उदाहरण के प्रकार पर वर्चुअल विधि को ओवरराइट किया जा सकता है। सभी उप-वर्ग ओवरलोडेड फ़ंक्शन के समान कार्यान्वयन को साझा कर सकते हैं। यही कारण है कि आप उन्हें दोनों स्थिर और आभासी बनाना चाहते हैं। यह देर से स्थिर बाध्यकारी है, PHP5 में उपलब्ध है। - Alex Weinstein
नहीं, कोई विरोधाभास नहीं है, यह पूरी तरह से संकलक समर्थन का विषय है, और पाइथन जैसी कई भाषाएं इसे करती हैं। वे प्रथम श्रेणी के वर्गों के साथ ऐसा करते हैं। यही वह वर्ग है जो स्वयं वस्तुएं हैं जिन्हें चर के लिए असाइन किया जा सकता है और उनकी विधियों को बुलाया जा सकता है। (अधिक जानने के लिए "classmethod" के लिए खोजें।) - Daniel Newby
ऑब्जेक्ट पास्कल (डेल्फी और ओपन सोर्स लाज़र समकक्ष) ने हमेशा उनका समर्थन किया है - Carlo Sirna


तुम पागल नहीं हो आप जो संदर्भ दे रहे हैं उसे लेट स्टेटिक बाइंडिंग कहा जाता है; इसे हाल ही में PHP में जोड़ा गया है। एक महान धागा है जो इसका वर्णन करता है - यहां: आपको देर से स्थिर बाध्यकारी उपयोग करने की आवश्यकता कब होगी?


6
2017-10-30 19:45





मार्ट को 'नया' कीवर्ड के साथ सही मिला। मैं वास्तव में यहां आया क्योंकि मुझे इस प्रकार की कार्यक्षमता की आवश्यकता थी और मार्ट का समाधान ठीक काम करता है। असल में मैंने इसे बेहतर तरीके से लिया और प्रोग्रामर को इस क्षेत्र की आपूर्ति के लिए मजबूर करने के लिए अपना बेस क्लास विधि सार बनाया।

मेरा परिदृश्य इस प्रकार था:

मेरे पास बेस क्लास हाउसडिड है। हाउस हाउस के प्रत्येक हाउस प्रकार से लिया गया मूल्य होना चाहिए।

यहां आंशिक आधार हाउसडिड क्लास है:

public abstract class HouseDeed : Item
{
    public static int m_price = 0;
    public abstract int Price { get; }
    /* more impl here */
}

अब दो व्युत्पन्न घर प्रकारों को देखें:

public class FieldStoneHouseDeed : HouseDeed
{
    public static new int m_price = 43800;
    public override int Price { get { return m_price; } }
    /* more impl here */
}

तथा...

public class SmallTowerDeed : HouseDeed
{
    public static new int m_price = 88500;
    public override int Price { get { return m_price; } }
    /* more impl here */
}

जैसा कि आप देख सकते हैं कि मैं SmallTowerDeed.m_price के प्रकार के माध्यम से घर की कीमत तक पहुंच सकता हूं, और उदाहरण के लिए नया SmallTowerDeed () मूल्य और अमूर्त होने के नाते, यह तंत्र प्रोग्रामर को प्रत्येक नए व्युत्पन्न घर के प्रकार के लिए कीमत की आपूर्ति करने के लिए तैयार करता है।

किसी ने इंगित किया कि 'स्थिर वर्चुअल' और 'वर्चुअल' एक दूसरे के साथ बाधाओं पर अवधारणात्मक रूप से कैसे हैं। मैं असहमत हूं। इस उदाहरण में, स्थैतिक तरीकों को आवृत्ति डेटा तक पहुंच की आवश्यकता नहीं है, और इसलिए आवश्यकताएं (1) कीमत केवल TYPE के माध्यम से उपलब्ध हो सकती हैं, और वह (2) आपूर्ति की जाने वाली कीमत पूरी की जाती है।


2
2018-05-30 16:44



यह उत्तर केवल प्रश्न से संबंधित रूप से संबंधित प्रतीत होता है। यह भी कुछ हद तक खराब उदाहरण है। m_price एक कार्यान्वयन विस्तार है और हाउसडिड का हिस्सा बनकर कुछ भी नहीं जोड़ता है। हाउसडिड से इसे निकालना और दोनों उप-वर्गों में m_price निजी बनाना बेहतर होगा। 'नए' कीवर्ड के दुरुपयोग के बिना वही परिणाम। - Rob McCready


मैंने सुना है कि डेल्फी इस तरह कुछ पसंद करता है। ऐसा लगता है कि यह मेटाक्लास के वर्ग ऑब्जेक्ट उदाहरण बनाकर करता है।

मैंने इसे काम नहीं देखा है, इसलिए मुझे यकीन नहीं है कि यह काम करता है, या उसके लिए क्या बात है।

अनुलेख अगर मैं गलत हूं तो कृपया मुझे सही करें, क्योंकि यह मेरा डोमेन नहीं है।


1
2017-10-29 20:26