?? खाली स्ट्रिंग के लिए सहूलियत?


165

कुछ ऐसा जो मैं खुद को अधिक से अधिक कर रहा हूं, खाली (जैसे ""या अशक्त) और एक सशर्त ऑपरेटर के लिए एक स्ट्रिंग की जांच कर रहा हूं ।

एक वर्तमान उदाहरण:

s.SiteNumber.IsNullOrEmpty() ? "No Number" : s.SiteNumber;

यह सिर्फ एक विस्तार विधि है, यह इसके बराबर है:

string.IsNullOrEmpty(s.SiteNumber) ? "No Number" : s.SiteNumber;

चूंकि यह खाली है और अशक्त नहीं है, इसलिए यह ??चाल नहीं चलेगी। का एक string.IsNullOrEmpty()संस्करण ??सही समाधान होगा। मुझे लगता है कि ऐसा करने का एक क्लीनर तरीका होना चाहिए (मुझे उम्मीद है!), लेकिन मुझे इसे खोजने का नुकसान हुआ है।

क्या किसी को यह करने का एक बेहतर तरीका पता है, भले ही यह केवल .net 4.0 में हो?


11
बस आपको थोड़ा सा टैंटलाइज़ करने के लिए, आप आसानी से एफ # में कस्टम, एड-हॉक बाइनरी (और इस मामले के लिए एकात्मक) ऑपरेटरों को परिभाषित कर सकते हैं। यहाँ let (|?) x y = if String.IsNullOrEmpty(x) then y else xऔर इसका उपयोग की तरह s.SiteNumber |? "No Number"
स्टीफन स्वेनसेन

जवाबों:


72

ऐसा करने का कोई अंतर्निहित तरीका नहीं है। आप अपनी एक्सटेंशन विधि को एक स्ट्रिंग या अशक्त रिटर्न दे सकते हैं, हालांकि, जो कि ऑपरेटर को काम करने की अनुमति देगा। हालांकि, यह अजीब होगा, और मैं व्यक्तिगत रूप से आपके वर्तमान दृष्टिकोण को पसंद करता हूं।

चूँकि आप पहले से ही एक्सटेंशन विधि का उपयोग कर रहे हैं, तो क्यों न केवल एक मूल्य या एक डिफ़ॉल्ट लौटाया जाए:

string result = s.SiteNumber.ConvertNullOrEmptyTo("No Number");

7
मुझे लगता है कि आप सही हैं, और यह वर्तमान में उपलब्ध सबसे साफ समाधान है जो अभी भी पढ़ने योग्य है। मुझे ???C # 5 में एक ऑपरेटर जैसा कुछ पसंद है , हालांकि, कौन जानता है।
निक Craver

2
और क्या होगा ??? ऑपरेटर करते हैं? nulls के अलावा डिफ़ॉल्ट मान लें? बहुत ही बेहतरीन लगता है
बेवकाक्

1
शायद मेमने के भाव के साथ? उदाहरण के लिए: मान लें कि "आइटम" item ?? x=> x.ToString() : null;
अशक्त है

@IsaacLlopis जो ओपी के मूल स्निपेट की तुलना में गन्दा-एर
दिख रहा है

133

सी # पहले से ही हमारे लिए मानों को बदल देता है nullके साथ ??। तो हम सभी की जरूरत है एक एक्सटेंशन है जो एक खाली स्ट्रिंग को धर्मान्तरित करता है null, और फिर हम इसे इस तरह उपयोग करते हैं:

s.SiteNumber.NullIfEmpty() ?? "No Number";

एक्सटेंशन क्लास:

public static class StringExtensions
{
    public static string NullIfEmpty(this string s)
    {
        return string.IsNullOrEmpty(s) ? null : s;
    }
    public static string NullIfWhiteSpace(this string s)
    {
        return string.IsNullOrWhiteSpace(s) ? null : s;
    }
}

44

मुझे पता है कि यह एक पुराना सवाल है - लेकिन मैं एक उत्तर की तलाश में था और उपरोक्त में से कोई भी मेरी ज़रूरत के अनुसार फिट नहीं था और साथ ही साथ मैंने क्या किया:

private static string Coalesce(params string[] strings)
{
    return strings.FirstOrDefault(s => !string.IsNullOrEmpty(s));
}

उपयोग:

string result = Coalesce(s.SiteNumber, s.AltSiteNumber, "No Number");

संपादित करें: इस फ़ंक्शन को लिखने का एक और अधिक कॉम्पैक्ट तरीका होगा:

static string Coalesce(params string[] strings) => strings.FirstOrDefault(s => !string.IsNullOrEmpty(s));

1
मुझे पसंद है, लेकिन एक संकलक त्रुटि को ठीक करना पड़ा और इसे थोड़ा और अधिक कॉम्पैक्ट बना दिया।
gregmac

जब आप मानों को एक साथ नहीं लाते हैं तो आप इस कोलेसस को क्यों कहते हैं, लेकिन जो खाली नहीं है उसका चयन करता है? यह एक भ्रामक नाम है दोस्त।
जिममिथ १

8
क्योंकि Coalesce एक ही ऑपरेशन को करने के लिए कई डेटाबेस द्वारा उपयोग किया जाने वाला शब्द है (पहले गैर-शून्य मान खोजें)। एक साथ तार जुड़ना संघटन है।
कैमरन फॉरवर्ड

सबसे अच्छा जवाब अगर आप कर रहे हैंusing System.Linq
जोपीसी

यह सुंदर, अच्छा काम है।
मारियानो लुइस विला

16

मेरे पास कुछ उपयोगिता एक्सटेंशन हैं जिनका मैं उपयोग करना चाहता हूं:

public static string OrDefault(this string str, string @default = default(string))
{
    return string.IsNullOrEmpty(str) ? @default : str;
}

public static object OrDefault(this string str, object @default)
{
    return string.IsNullOrEmpty(str) ? @default : str;
}

संपादित करें: sfsr के उत्तर से प्रेरित होकर , मैं अब से अपने टूलबॉक्स में इस संस्करण को जोड़ूंगा :

public static string Coalesce(this string str, params string[] strings)
{
    return (new[] {str})
        .Concat(strings)
        .FirstOrDefault(s => !string.IsNullOrEmpty(s));
}

1
मैं निश्चित रूप से "कोलेसस" शब्द का उपयोग कर रहा हूं, क्योंकि यह अधिक बारीकी से नल सहवर्ती ऑपरेटर (??) के इरादे से मिलता-जुलता है, हालांकि मैंने इसे "कोलेससेटो" में बदल दिया है।
31:12

पैरामीटर @पर उपसर्ग क्या करता @defaultहै? मैंने ऐसा पहले कभी नहीं देखा।
आकर्षित चैपिन

3
@druciferre - यह आपको defaultC # में एक आरक्षित कीवर्ड होते हुए भी एक चर नाम के रूप में उपयोग करने की अनुमति देता है ।
जस्टिन मॉर्गन

1
@ Jimmyt1988 - क्योंकि यह मानक T-SQL COALESCE फ़ंक्शन का अनुमान लगाता है ।
जस्टिन मॉर्गन

1
@ Jimmyt1988 - यह भी क्योंकि यह विशेष रूप से एक मनमाना-लंबाई सूची में पहले गैर-खाली फ़ंक्शन का चयन करता है । यह एक सूक्ष्म विवरण है, लेकिन टी-एसक्यूएल फ़ंक्शन उसी तरह काम करता है। नाम किसी को भी, जो उस फ़ंक्शन को जानता है, जो प्रलेखन के साथ या उसके बिना इसे सहज बनाता है।
जस्टिन मॉर्गन

6

प्रस्तावित पहले की तुलना में थोड़ा तेज़ विस्तार विधि:

public static string Fallback(this string @this, string @default = "")
{
    return (@this == null || @this.Trim().Length == 0) ? @default : @this;
}

11
ट्रिम और लंबाई के बजाय IsNullOrWhitespace का उपयोग क्यों न करें ।
पश्चिम दिशा में

1
codeसार्वजनिक स्थैतिक स्ट्रिंग कोलेस (यह स्ट्रिंग @this, string @default = "") {वापसी (@this== null)। String.IsNullOrWhiteSpace (@this))? @ डेफॉल्ट: @this; }
पॉल-2011

6

नल-कोलेसिंग ऑपरेटर के लाभों में से एक यह है कि यह शॉर्ट-सर्किट है। जब पहला भाग शून्य नहीं होता है, तो दूसरे भाग का मूल्यांकन नहीं किया जाता है। यह तब उपयोगी हो सकता है जब फॉलबैक को एक महंगे ऑपरेशन की आवश्यकता हो।

मैं इसके साथ समाप्त हुआ:

public static string Coalesce(this string s, Func<string> func)
{
    return String.IsNullOrEmpty(s) ? func() : s;
}

उपयोग:

string navigationTitle = model?.NavigationTitle.
    Coalesce(() => RemoteTitleLookup(model?.ID)). // Expensive!
    Coalesce(() => model?.DisplayName);

6

मैं बस एक NullIfEmpty एक्सटेंशन विधि का उपयोग करता हूं जो स्ट्रिंग की अनुमति देने पर हमेशा शून्य वापस आ जाएगी ?? (नल कोलेसिंग ऑपरेटर) को सामान्य के रूप में उपयोग किया जाना है।

public static string NullIfEmpty(this string s)
{
    return s.IsNullOrEmpty() ? null : s;
}

यह तो अनुमति देता है ?? सामान्य के रूप में इस्तेमाल किया जा सकता है और पढ़ने में आसान बनाता है।

string string1 = string2.NullIfEmpty() ?? string3.NullIfEmpty() ?? string4;

3

कैसे एक स्ट्रिंग विस्तार विधि के बारे में ValueOrDefault ()

public static string ValueOrDefault(this string s, string sDefault)
{
    if (string.IsNullOrEmpty(s))
        return sDefault;
    return s;
}

या वापसी शून्य अगर स्ट्रिंग खाली है:

public static string Value(this string s)
{
    if (string.IsNullOrEmpty(s))
        return null;
    return s;
}

हालांकि इन समाधानों की कोशिश नहीं की।


2
मुझे वहाँ # 1 विकल्प पसंद है, हालाँकि मैं इसे कुछ और शब्दार्थ (या) कहूँगा, इसलिए मैं "string s = s.SiteNumber.Or (" डिफ़ॉल्ट ") लिख सकता हूँ;"
jvenema

2
किसी चीज़ ...OrDefault()को कॉल करना भ्रामक होगा यदि यह बाकी ढांचे के ...OrDefault()तरीकों की तरह व्यवहार नहीं करता है । यह पसंद है या नहीं, एमएस ने एक विशिष्ट अर्थ दिया है कि कस्टम तरीकों में उस व्यवहार से नामकरण और विचलन अनावश्यक रूप से आपके एपीआई के उपयोगकर्ताओं को भ्रमित कर रहा है।
Mattmc3

3

मैं अपने खुद के एक स्ट्रिंग कोलेसस एक्सटेंशन विधि का उपयोग कर रहा हूं। चूँकि यहाँ वो लोग LINQ, और निरपेक्ष रूप से समय बर्बाद करने वाले संसाधनों का गहन संचालन के लिए उपयोग कर रहे हैं (मैं इसे तंग छोरों में उपयोग कर रहा हूँ), मैं आपको साझा करूँगा "

public static class StringCoalesceExtension
{
    public static string Coalesce(this string s1, string s2)
    {
        return string.IsNullOrWhiteSpace(s1) ? s2 : s1;
    }
}

मुझे लगता है कि यह काफी सरल है, और आपको अशक्त स्ट्रिंग मानों से परेशान होने की आवश्यकता नहीं है। इसे इस तरह उपयोग करें:

string s1 = null;
string s2 = "";
string s3 = "loudenvier";
string s = s1.Coalesce(s2.Coalesce(s3));
Assert.AreEqual("loudenvier", s);

मैंने इसे बहुत इस्तेमाल किया है। उन "उपयोगिता" कार्यों में से एक जिन्हें आप पहली बार उपयोग करने के बाद बिना नहीं रह सकते हैं :-)


मुझे नहीं लगता कि आप समझते हैं कि वे LINQ का उपयोग क्यों कर रहे हैं, और चूंकि कॉल से पहले मापदंडों का मूल्यांकन किया s2.Coalesce(s3)जाता है , आपकी आवश्यकता होने पर भी चलाया जाता है। एक NullIfEmpty()एक्सटेंशन का उपयोग करने के लिए बेहतर है और ??
नेटमैज

@NetMage मैं आपको गारंटी दे सकता हूं कि LINQ संस्करण मेरे द्वारा प्रस्तुत किए गए की तुलना में बहुत कम प्रदर्शन कर रहे हैं। आप चाहें तो इसे टेस्ट करने के लिए एक साधारण बेंचमार्क बना सकते हैं। मैं बेंचमार्किंग कोड लिखते समय आम नुकसान को रोकने के लिए github.com/dotnet/BenchmarkDotNet का उपयोग करने का सुझाव देता हूं ।
लॉडनवीयर

0

मुझे इसके लिए निम्नलिखित विस्तार विधि की संक्षिप्तता पसंद है QQQ, हालांकि निश्चित रूप से एक ऑपरेटर की तरह? बेहतर होगा। लेकिन हम इसे केवल दो नहीं बल्कि तीन स्ट्रिंग विकल्प मानों की तुलना करके अनुमति दे सकते हैं, जो हर अब और फिर (दूसरा फ़ंक्शन नीचे देखें) को संभालने की आवश्यकता का सामना करता है।

#region QQ

[DebuggerStepThrough]
public static string QQQ(this string str, string value2)
{
    return (str != null && str.Length > 0)
        ? str
        : value2;
}

[DebuggerStepThrough]
public static string QQQ(this string str, string value2, string value3)
{
    return (str != null && str.Length > 0)
        ? str
        : (value2 != null && value2.Length > 0)
            ? value2
            : value3;
}


// Following is only two QQ, just checks null, but allows more than 1 string unlike ?? can do:

[DebuggerStepThrough]
public static string QQ(this string str, string value2, string value3)
{
    return (str != null)
        ? str
        : (value2 != null)
            ? value2
            : value3;
}

#endregion

यदि आपको छोटे नाम पसंद हैं, तो आप इसे कॉल कर सकते हैं Or, और मैं paramsकीवर्ड का उपयोग अन्य उत्तरों की तरह करूँगा , जो कई मापदंडों के लिए डुप्लिकेट परिभाषाओं से बचा जाता है।
चिले दस ब्रिंच

विचार के लिए धन्यवाद। मैंने लंबे समय से इस नाम को अपने उपयोग में "FirstNotNull" के साथ बदल दिया है। पर params, यह बेहतर होगा कि डिफ़ॉल्ट परिदृश्य या दो के लिए, क्योंकि paramsकिसी सरणी को अनावश्यक रूप से आवंटित किए जाने का कारण बनता है जब आपके पास केवल डिफ़ॉल्ट एक या दो इनपुट होते हैं। उसके बाद समझ में आता है।
निकोलस पीटरसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.