यदि सामान्य प्रकार एक स्ट्रिंग है तो परीक्षण करने का सबसे अच्छा तरीका है? (सी#)


93

मेरे पास एक सामान्य वर्ग है जो किसी भी प्रकार, आदिम या अन्यथा की अनुमति देना चाहिए। इसके साथ एकमात्र समस्या का उपयोग कर रहा है default(T)। जब आप किसी मान प्रकार या स्ट्रिंग पर डिफ़ॉल्ट कॉल करते हैं, तो यह इसे एक उचित मान (जैसे कि रिक्त स्ट्रिंग) के लिए प्रारंभ करता है। जब आप default(T)किसी ऑब्जेक्ट पर कॉल करते हैं, तो यह अशक्त हो जाता है। विभिन्न कारणों से हमें यह सुनिश्चित करने की आवश्यकता है कि यदि यह एक आदिम प्रकार नहीं है, तो हमारे पास प्रकार का डिफ़ॉल्ट उदाहरण होगा, शून्य नहीं । यहाँ प्रयास 1 है:

T createDefault()
{
    if(typeof(T).IsValueType)
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance<T>();
    }
}

समस्या - स्ट्रिंग एक मान प्रकार नहीं है, लेकिन इसमें एक पैरामीटर रहित निर्माता नहीं है। तो, वर्तमान समाधान है:

T createDefault()
{
    if(typeof(T).IsValueType || typeof(T).FullName == "System.String")
    {
        return default(T);
    }
    else
    {
        return Activator.CreateInstance<T>();
    }
}

लेकिन यह एक कीचड़ की तरह लगता है। क्या स्ट्रिंग केस को संभालने का एक अच्छा तरीका है?

जवाबों:


161

ध्यान रखें कि डिफ़ॉल्ट (स्ट्रिंग) शून्य है, न कि स्ट्रिंग। खाली। आप अपने कोड में एक विशेष मामला चाहते हैं:

if (typeof(T) == typeof(String)) return (T)(object)String.Empty;

2
मुझे लगा कि मैंने पहले ही उस समाधान की कोशिश की थी और यह काम नहीं किया, लेकिन मैंने कुछ बेवकूफी की है। और डिफ़ॉल्ट (स्ट्रिंग) रिटर्न को इंगित करने के लिए धन्यवाद अशक्त है, हम इसके कारण अभी तक एक त्रुटि में नहीं चले थे, लेकिन यह सच है।
रेक्स एम

1
@Matt हैमिल्टन: +1, लेकिन आपको अपना जवाब 'T (T) (ऑब्जेक्ट) String.Empty' को अपडेट करना चाहिए जैसा कि CodeInChaos द्वारा सुझाया गया है क्योंकि विधि वापसी प्रकार सामान्य है, आप केवल स्ट्रिंग वापस नहीं कर सकते।
वूडूचाइल्ड

2
isकीवर्ड के बारे में क्या ? यहाँ उपयोग नहीं है?
नवेद बट

फिलहाल यह संभव नहीं है कि जेनेरिक और असाइनमेंट या डायरेक्ट इंस्टेंस के साथ ऑपरेटर लागू हो, है न?, एक शानदार फीचर होगा
जुआन पाब्लो गार्सिया कोएलो

14
if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
     return default(T);
}
else
{
     return Activator.CreateInstance<T>();
}

अनकहा, लेकिन पहली बात जो मन में आई।


4

आप उपयोग कर सकते हैं टाइपकोड एन्यूमरेशन का । उस श्रेणी के उदाहरण के लिए टाइप कोड प्राप्त करने के लिए IConvertible इंटरफ़ेस को लागू करने वाली कक्षाओं पर GetTypeCode विधि को कॉल करें। IConvertible को Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, और String द्वारा कार्यान्वित किया जाता है, इसलिए आप इसका उपयोग करके आदिम प्रकारों की जांच कर सकते हैं। " सामान्य प्रकार की जाँच " पर अधिक जानकारी ।


2

व्यक्तिगत रूप से, मुझे विधि अधिभार पसंद है:

public static class Extensions { 
  public static String Blank(this String me) {      
    return String.Empty;
  }
  public static T Blank<T>(this T me) {      
    var tot = typeof(T);
    return tot.IsValueType
      ? default(T)
      : (T)Activator.CreateInstance(tot)
      ;
  }
}
class Program {
  static void Main(string[] args) {
    Object o = null;
    String s = null;
    int i = 6;
    Console.WriteLine(o.Blank()); //"System.Object"
    Console.WriteLine(s.Blank()); //""
    Console.WriteLine(i.Blank()); //"0"
    Console.ReadKey();
  }
}

0

मुझे पता है कि यह प्रश्न पुराना है, लेकिन एक अद्यतन किया गया है।

C # 7.0 के बाद से आप isऑपरेटर का उपयोग प्रकारों की तुलना करने के लिए कर सकते हैं । अब आपको typeofस्वीकृत उत्तर में उपयोग की आवश्यकता नहीं है ।

        public bool IsObjectString(object obj)
        {
            return obj is string;
        }

https://docs.microsoft.com/en-US/dotnet/csharp/language-reference/keywords/is


-6

स्ट्रिंग के लिए चर्चा यहाँ काम नहीं कर रही है।

मुझे यह काम करने के लिए जेनेरिक के लिए निम्नलिखित कोड होना चाहिए -

   private T createDefault()
    { 

        {     
            if(typeof(T).IsValueType)     
            {         
                return default(T);     
            }
            else if (typeof(T).Name == "String")
            {
                return (T)Convert.ChangeType(String.Empty,typeof(T));
            }
            else
            {
                return Activator.CreateInstance<T>();
            } 
        } 

    }

3
Stringनाम से परीक्षण , विशेष रूप से बिना किसी नामस्थान के परीक्षण खराब है। और मुझे वह तरीका पसंद नहीं है जो आप या तो रूपांतरित करते हैं।
कोडइन्चोज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.