के साथ काम नहीं करता है क्या यह एक कंपाइलर बग है या क्या कोई विशिष्ट कारण है कि शून्य-सशर्त ऑपरेटर सामान्य तरीकों के अंदर Func
के साथ काम नहीं करता है?शून्य-सशर्त ऑपरेटर फनक <T> के साथ एक सामान्य विधि
एक उदाहरण निम्नलिखित संकलन नहीं है देने के लिए
public static T Test<T>(Func<T> func)
{
return func?.Invoke() ?? default(T);
}
त्रुटि संकलक का उत्पादन CS0023 Operator '?' cannot be applied to operand of type 'T'
है मुझे पता है कि आप इस हालांकि कर एक ही प्राप्त कर सकते हैं कर रहा हूँ:
public static T Test<T>(Func<T> func)
{
return func != null ? func() : default(T);
}
तो ऐसा क्यों है कि इसकी अनुमति नहीं है?
आगे Action<T>
विस्तृत करने के लिए अपेक्षा के अनुसार काम करता है।
public static void Test<T>(Action<T> action, T arg)
{
action?.Invoke(arg);
}
अद्यतन (2017/01/17):
कुछ और अनुसंधान के बाद, यह भी कम समझ में आता है, यहां तक कि निम्नलिखित के साथ:
मान लीजिए कि हम एक वर्ग करते हैं (संदर्भ प्रकार)
public class Foo
{
public int Bar { get; set; }
}
और मान लीजिए कि हम एक Func<int>
Func<int> fun =() => 10;
निम्नलिखित काम करता है:
// This work
var nullableBar = foo?.Bar; // type of nullableBar is int?
var bar = nullableBar ?? default(int); // type of bar is int
// And this work
nullableBar = fun?.Invoke(); // ditto
bar = nullableBar ?? default(int); // ditto
कौन सा तर्क के अनुसार अर्थ है वहाँ लागू किया गया फिर एक मूल्य के प्रकार null-conditional
और null-coalescing
ऑपरेटर्स का उपयोग कर काम करना चाहिए की एक Func<T>
।
हालांकि जैसे ही बाएं हाथ null-conditional
के जेनेरिक प्रकार बगैर किसी अड़चन के साथ सामान्य है तो यह एक ही तर्क है कि यह यह दोनों मूल्य-प्रकार के लिए एक ही तर्क लागू कर सकते हैं पर विचार करने के लिए सक्षम होना चाहिए लागू नहीं कर सकते और संदर्भ-प्रकार जब प्रकार स्पष्ट रूप से लागू होते हैं।
मुझे कंपेलरों की बाधाओं के बारे में पता है, यह मुझे समझ में नहीं आता है कि यह क्यों अनुमति नहीं देता है और क्यों यह आउटपुट अलग होना चाहता है कि यह संदर्भ या मूल्य प्रकार है जो मैन्युअल रूप से प्रकारों को लागू करने पर विचार करता है अपेक्षित परिणाम मिलेगा।
'वर एक्स = समारोह लंबे प्रपत्र आप से पता चला है का उपयोग करें या विभिन्न बाधाओं के साथ दो विधियों की आवश्यकता होगी? .Invoke()' भी असफल हो जायेगी। 'x' शून्य हो सकता है या कुछ मूल्य हो सकता है। कंपाइलर यह नहीं जानता है। इसके अलावा उस कंपाइलर को यह नहीं पता कि 'टी' संदर्भ प्रकार है या नहीं। ध्यान दें कि 'शून्य' मूल्य प्रकारों पर मान्य नहीं है। उदाहरण के लिए आप 'int I = null' लिख नहीं सकते हैं। इस प्रकार आपको मिली त्रुटि। –
संक्षेप में, 'Func' का प्रकार? अगर 'टी' संदर्भ प्रकार है, और' टी? '' '' '' '' '' '' '' होना चाहिए। चूंकि .NET में जेनेरिकों में एक कार्यान्वयन है (जैसा कि सी ++ में टेम्पलेट्स के विपरीत है), यह आसानी से नहीं किया जा सकता है। सिद्धांत रूप में, संकलक चालाक कोड पीढ़ी द्वारा इस काम को करने के लिए पीछे की तरफ मोड़ सकता है। प्रैक्टिस में, सी # कंपाइलर का दर्शन पीछे की तरफ झुकना नहीं है, लेकिन चीजों को अस्वीकार करना है अगर उन्हें सीधे तौर पर नहीं किया जा सकता है। –