सामान्य प्रकार की जांच

Is there a way to enforce/limit the types that are passed to primitives? (bool, int, string, etc.)

अब, मुझे पता है कि आप सामान्य प्रकार पैरामीटर को किसी प्रकार या इंटरफ़ेस कार्यान्वयन को कहां खंड के माध्यम से सीमित कर सकते हैं। हालांकि, यह प्राइमेटिव्स (AFAIK) के लिए बिल में फिट नहीं है क्योंकि किसी के कहने से पहले उनके पास एक सामान्य जमीन नहीं है ( ऑब्जेक्ट के अलावा!) पी)।

तो, मेरे वर्तमान विचार सिर्फ मेरे दांतों को गले लगाने और बड़े स्विच कथन को करने और विफलता पर ArgumentException फेंकना है ..


संपादित करें 1:

केवल स्पष्ट करने हेतु:

कोड परिभाषा इस तरह होनी चाहिए:

public class MyClass ....

और तत्काल:

MyClass = new MyClass();//Legal
MyClass = new MyClass();//Legal
MyClass = new MyClass();//Illegal
MyClass = new MyClass();//Illegal (but looks awesome!)

EDIT 2

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

यह उन वस्तुओं को तुरंत हटाने में उपयोगी हो सकता है जिनसे मैं निपटना नहीं चाहता हूं (लेकिन फिर आपको उन structs के बारे में चिंता करने की ज़रूरत है, जिनका उपयोग आकार ) .. दिलचस्प समस्या नहीं है? :)

यह रहा:

where T : struct

MSDN से लिया गया।


मैं उत्सुक हूँ .. क्या यह एक्सटेंशन विधियों का उपयोग कर .NET 3.x में किया जा सकता है? एक इंटरफ़ेस बनाएं, और एक्सटेंशन विधियों में इंटरफ़ेस को कार्यान्वित करें (जो शायद थोड़ा वसा स्विच से क्लीनर होगा)। इसके अलावा यदि आपको बाद में किसी भी हल्के कस्टम प्रकार तक विस्तार करने की आवश्यकता है, तो वे बेस कोड में आवश्यक परिवर्तनों के साथ ही एक ही इंटरफेस को कार्यान्वित कर सकते हैं।

आप लोग क्या सोचते हैं?

दुखद खबर यह है कि मैं फ्रेमवर्क 2 में काम कर रहा हूं !! : डी


EDIT 3

यह जॉन लिमजैप्स पॉइंटर से बहुत आसान था .. इतना आसान मैं लगभग रोना चाहता हूं, लेकिन यह बहुत अच्छा है क्योंकि कोड एक आकर्षण की तरह काम करता है!

तो यहां मैंने जो किया है (आप हँसेंगे!):

कोड जेनेरिक वर्ग में जोड़ा गया

bool TypeValid()
{
   //Get the TypeCode from the Primitive Type
    TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));

   //All of the TypeCode Enumeration refer Primitive Types
   //with the exception of Object and Empty (Null).
   //Since I am willing to allow Null Types (at this time)
   //all we need to check for is Object!
    switch (code)
    {
        case TypeCode.Object:
            return false;
        default:
            return true;
    }
}

फिर प्रकार की जांच करने और अपवाद फेंकने के लिए एक छोटी उपयोगिता विधि,

private void EnforcePrimitiveType()
{
    if (!TypeValid())
        throw new InvalidOperationException(
            "Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name + 
            "' - this Class is Designed to Work with Primitive Data Types Only.");
}

तब सभी को कक्षाओं के रचनाकारों में EnforcePrimitiveType() को कॉल करने की आवश्यकता है। काम हो गया! :-)

केवल एक ही नकारात्मक, यह केवल डिजाइन समय के बजाए रनटाइम (स्पष्ट रूप से) पर अपवाद फेंकता है .. लेकिन यह कोई बड़ा सौदा नहीं है और इसे FxCop (जिसे हम काम पर उपयोग नहीं करते हैं)।

इस पर जॉन लिमजप के लिए विशेष धन्यवाद!

0
ro fr bn
आप अपने स्थिर कन्स्ट्रक्टर में चेक भी कॉल कर सकते हैं, इसलिए इसे सामान्य तर्क के रूप में उपयोग किए जाने वाले प्रति प्रकार केवल एक बार कहा जाता है।
जोड़ा लेखक Julien, स्रोत

8 उत्तर

0
जोड़ा
खैर, मुझे नहीं पता कि वस्तुओं और प्राइमेटिव्स के बीच विवाद का मुख्य बिंदु यह है कि अधिकांश प्राइमेटिव वास्तव में कक्षाएं हैं, वर्ग नहीं। मैं उन्हें प्रोग्रामेटिक रूप से समझने का एक तरीका ढूंढूंगा :)
जोड़ा लेखक Jon Limjap, स्रोत
> पब्लिक क्लास क्लास 1 <�जेनेरिक टाइप> जहां> जेनेरिक टाइप: स्ट्रक्चर {}>> यह एक नौकरी करना प्रतीत होता है .. समस्या जो मैं उस कार्यान्वयन के साथ देखता हूं वह यह है कि यदि आपके पास कस्टम स्ट्रक्चर है तो यह अभी भी एक आदिम के रूप में आ जाएगा, जो ऐसा नहीं है।
जोड़ा लेखक Jon Limjap, स्रोत
अच्छा बिंदु, और कुछ जो मैं पहले से ही विचार कर रहा था .. मुझे यकीन है कि एक सामान्य विधि है जिसका उपयोग यह निर्धारित करने के लिए किया जा सकता है कि प्रकार एक मान या संदर्भ प्रकार है या नहीं। यह बहुत सारी वस्तुओं को तुरंत हटाने में उपयोगी हो सकता है मैं इससे निपटना नहीं चाहता (लेकिन फिर आपको उन structs के बारे में चिंता करने की ज़रूरत है जिन्हें आकार ) उपयोग किया जाता है .. दिलचस्प समस्या नहीं? :) संपादित करें: आह हाँ, यहां यह है: जहां टी: संरचना एमएसडीएन
जोड़ा लेखक Rob Cooper, स्रोत
मैं उत्सुक हूँ .. मुझे आश्चर्य है कि यह एक्सटेंशन विधियों का उपयोग कर .NET 3.x में किया जा सकता है .. एक इंटरफ़ेस बनाएं .. एक्सटेंशन विधियों में इंटरफ़ेस को कार्यान्वित करें .. (जो शायद थोड़ा वसा स्विच से क्लीनर होगा) .. इसके अलावा यदि आपको बाद में किसी भी हल्के कस्टम प्रकार तक विस्तार करने की आवश्यकता है, तो वे बेस कोड में आवश्यक परिवर्तनों के साथ ही एक ही इंटरफेस को कार्यान्वित कर सकते हैं। आप लोग क्या सोचते हैं? दुखद खबर यह है कि मैं ढांचे 2 में काम कर रहा हूं !! : डी <�बी> संपादित करें: कार्यालय को 5 मिनट की तरह छोड़ना, जब मैं घर वापस आऊंगा तो इसे उठाऊंगा! : डी
जोड़ा लेखक Rob Cooper, स्रोत

बहुत कुछ क्या @Lars पहले से ही कहा:

//Force T to be a value (primitive) type.
public class Class1 where T: struct

//Force T to be a reference type.
public class Class1 where T: class

//Force T to be a parameterless constructor.
public class Class1 where T: new()

.NET 2, 3 और 3.5 में सभी काम।

0
जोड़ा
public class Class1 where GenericType : struct
{
}

यह नौकरी करना प्रतीत होता था ..

0
जोड़ा

यदि आप कारखाने के तरीकों का उपयोग कर सहन कर सकते हैं (इसके बजाय कन्स्ट्रक्टर माई क्लास के लिए आपने पूछा) तो आप हमेशा ऐसा कुछ कर सकते हैं:

class MyClass
{
  private readonly T _value;

  private MyClass(T value) { _value = value; }

  public static MyClass FromInt32(int value) { return new MyClass(value); }
  public static MyClass FromString(string value) { return new MyClass(value); }
 //etc for all the primitive types, or whatever other fixed set of types you are concerned about
}

A problem here is that you would need to type MyClass.FromInt32, which is annoying. There isn't a very good way around this if you want to maintain the private-ness of the constructor, but here are a couple of workarounds:

  • Create an abstract class MyClass. Make MyClass inherit from MyClass and nest it within MyClass. Move the static methods to MyClass. This will all the visibility work out, at the cost of having to access MyClass as MyClass.MyClass.
  • Use MyClass as given. Make a static class MyClass which calls the static methods in MyClass using MyClass (probably using the appropriate type each time, just for giggles).
  • (Easier, but certainly weird) Make an abstract type MyClass which inherits from MyClass. (For concreteness, let's say MyClass.) Because you can call static methods defined in a base class through the name of a derived class, you can now use MyClass.FromString.

यह आपको अधिक लेखन की कीमत पर स्थिर जांच देता है।

यदि आप गतिशील जांच से खुश हैं, तो मैं उपरोक्त टाइपकोड समाधान पर कुछ भिन्नता का उपयोग करूंगा।

0
जोड़ा

आप EnforcePrimitiveType विधि को सरल बना सकते हैं। > टाइपऑफ (PrimitiveDataType) Isprrimitive संपत्ति। क्या मैं कुछ भूल रहा हूँ?

0
जोड़ा
उस कथन में एक स्ट्रिंग पास करना गलत होता है, और पोस्टर निर्दिष्ट करता है कि उसे सही लौटने के लिए स्ट्रिंग की आवश्यकता होती है। .NET char को एक आदिम मानता है, लेकिन स्ट्रिंग नहीं।
जोड़ा लेखक Nicholas, स्रोत

Use a custom FxCop rule that flags undesirable usage of MyClass<>.

0
जोड़ा

@Rob, Enum की इच्छा TypeValid फ़ंक्शन के माध्यम से फिसल जाएगी क्योंकि यह TypeCode Integer है। मैंने Enum की जांच करने के लिए फ़ंक्शन को अपडेट किया है।

Private Function TypeValid() As Boolean
    Dim g As Type = GetType(T)
    Dim code As TypeCode = Type.GetTypeCode(g)

    ' All of the TypeCode Enumeration refer Primitive Types
    ' with the exception of Object and Empty (Nothing).
    ' Note: must also catch Enum as its type is Integer.
    Select Case code
        Case TypeCode.Object
            Return False
        Case Else
            ' Enum's TypeCode is Integer, so check BaseType
            If g.BaseType Is GetType(System.Enum) Then
                Return False
            Else
                Return True
            End If
    End Select
End Function
0
जोड़ा

एक समान चुनौती होने के बाद, मैं सोच रहा था कि आप लोगों को IConvertible इंटरफ़ेस । यह अनुरोधकर्ता को क्या चाहिए, इसकी अनुमति देता है, और आप अपने स्वयं के कार्यान्वयन के साथ विस्तार कर सकते हैं।

उदाहरण:

    public class MyClass
    where TKey : IConvertible
{
   //class intentionally abbreviated
}

मैं इस बारे में एक समाधान के रूप में सोच रहा हूं, हालांकि सुझाए गए कई मेरे चयन का हिस्सा भी थे।

मेरी चिंता है - हालांकि - क्या यह आपकी कक्षा का उपयोग कर संभावित डेवलपर्स के लिए भ्रामक है?

चीयर्स - और धन्यवाद।

0
जोड़ा