2016-09-12 15 views
11

के साथ काम नहीं कर रहा है क्यों सी # में स्ट्रिंग इंटरपोलेशन कॉन्स स्ट्रिंग के साथ काम नहीं करता है? उदाहरण के लिए:स्ट्रिंग इंटरपोलेशन क्यों कॉन्स्ट स्ट्रिंग्स

private const string WEB_API_ROOT = "/private/WebApi/"; 
private const string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json"; 

मेरे दृष्टिकोण से, सब कुछ संकलन समय पर जाना जाता है। या यह एक सुविधा है जिसे बाद में जोड़ा जाएगा?

संकलक संदेश:

The expression being assigned to 'DynamicWebApiBuilder.WEB_API_PROJECT' must be constant.

धन्यवाद एक बहुत!

+8

इंटरपोलेटेड तारों को केवल 'string.Format' कॉल में परिवर्तित कर दिया गया है। – juharr

+3

वर्कअराउंड के लिए, 'स्थिर' पढ़ने के साथ 'const' को प्रतिस्थापित करें –

+4

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

उत्तर

22

इंटरपोलेटेड तारों को आसानी से string.Format पर कॉल में परिवर्तित कर दिया जाता है। तो अपने ऊपर पंक्ति वास्तव में पढ़ता है

private const string WEB_API_PROJECT = string.Format("{0}project.json", WEB_API_ROOT); 

और इस बार लगातार संकलन नहीं कर रहा है के रूप में एक विधि कॉल शामिल है।


दूसरी ओर, स्ट्रिंग (सरल, निरंतर स्ट्रिंग शाब्दिक का) संयोजन संकलक द्वारा किया जा सकता है, तो यह काम करेगा:

private const string WEB_API_ROOT = "/private/WebApi/"; 
private const string WEB_API_PROJECT = WEB_API_ROOT + "project.json"; 

या conststatic readonly करने से स्विच:

private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json"; 

तो स्ट्रिंग किसी भी मेरे लिए सबसे पहले पहुंच पर आरंभ नहीं हो जाता है (और string.Format कहा जाता है) घोषणा प्रकार के मेबर।

+0

यह समझ में आता है। बहुत बहुत धन्यवाद :) – BendEg

+1

यह सरल रियायत स्पष्ट है, मैंने सोचा कि मैं भी इस नई सी # 6 सुविधा का उपयोग कर सकता हूं। – BendEg

+0

@Rene, यहां तक ​​कि [निजी स्थैतिक रीडोनली स्ट्रिंग] का उपयोग करके, कंपाइलर एक त्रुटि उठाता है "वर्तमान संदर्भ में 'WEB_API_ROOT' नाम मौजूद नहीं है"। वेरिएबल 'WEB_API_ROOT' को उसी संदर्भ में परिभाषित किया जाना चाहिए। –

9

एक अतिरिक्त स्पष्टीकरण क्यों स्ट्रिंग इंटरपोलेशन एक्सप्रेशन को स्थिरांक नहीं माना जाता है यह है कि वे स्थिर नहीं हैं, भले ही उनके सभी इनपुट स्थिरांक हों। विशेष रूप से, वे वर्तमान संस्कृति के आधार पर भिन्न होते हैं। कि उत्पादन अलग है

3.14 
3,14 

ध्यान दें, भले ही स्ट्रिंग प्रक्षेप अभिव्यक्ति दोनों ही मामलों में एक ही है: निम्नलिखित कोड को क्रियान्वित करने का प्रयास करें:

CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; 

Console.WriteLine($"{3.14}"); 

CultureInfo.CurrentCulture = new CultureInfo("cs-CZ"); 

Console.WriteLine($"{3.14}"); 

इसका उत्पादन होता है। तो, const string pi = $"{3.14}" के साथ, यह स्पष्ट नहीं होगा कि संकलक को कौन सा कोड उत्पन्न करना चाहिए।

4

वहाँ roslyn कि निम्नलिखित निष्कर्ष को अंतिम रूप देने में रोसलिन परियोजना में एक चर्चा है:

अंश पढ़ें:

It's not a bug, it was explicitly designed to function like this. You not liking it doesn't make it a bug. String.Format isn't needed for concatenating strings, but that's not what you're doing. You're interpolating them, and String.Format is needed for that based on the spec and implementation of how interpolation works in C#.

If you want to concatenate strings, go right ahead and use the same syntax that has worked since C# 1.0. Changing the implementation to behave differently based on usage would produce unexpected results:

const string FOO = "FOO"; 
    const string BAR = "BAR"; 
    string foobar = $"{FOO}{BAR}"; 
    const string FOOBAR = $"{FOO}{BAR}"; // illegal today 

    Debug.Assert(foobar == FOOBAR); // might not always be true 

भी बयान:

private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json"; 

संकलक एक त्रुटि उठाएं:

क्यों स्ट्रिंग प्रक्षेप स्थिरांक तार के साथ काम नहीं कर रहा है:
"The name 'WEB_API_ROOT' does not exist in the current context". 

चर 'WEB_API_ROOT' ओ पी के सवाल के लिए एक ही संदर्भ में परिभाषित किया जाना चाहिए

तो,? उत्तर: यह सी # 6 चश्मा द्वारा है। अधिक जानकारी के लिए .NET Compiler Platform ("Roslyn") -String Interpolation for C#

+0

ध्यान दें कि यहां ले जाने वाला यह कम या कम लगता है: एक अनुमानित डिफ़ॉल्ट संस्कृति को परिभाषित करना और सेट करना संभव है जो सभी स्वरूपित तारों को संशोधित करता है, जो 'string.Format()' कॉल के वापसी मूल्य को भी बदल देगा केवल 'const'' स्ट्रिंग की ** ** रनटाइम ** पर। चूंकि यह संस्कृति जांच प्रारंभिक प्रारंभकर्ता के दौरान सबसे अच्छी हो सकती है, लेकिन 'const' स्ट्रिंग मान सेट केवल कंपाइलर समय पर होता है, एक' const' interpolated स्ट्रिंग रनटाइम पर इंटरपोलेटेड स्ट्रिंग के मान के बराबर नहीं हो सकती है, अगर संकलन समय पर संस्कृति रनटाइम पर संस्कृति नहीं है। – jrh

संबंधित मुद्दे