मुझे पता है, मुझे पता है ... इस तरह के सवाल का एरिक लिपर्ट का जवाब आमतौर पर "जैसा कुछ होता है क्योंकि यह डिजाइन, कार्यान्वयन, परीक्षण और दस्तावेज बनाने की लागत के लायक नहीं था "।
लेकिन फिर भी, मैं एक बेहतर स्पष्टीकरण चाहता हूं ... मैं इस ब्लॉग पोस्ट को नई सी # 4 विशेषताओं के बारे में पढ़ रहा था , और COM इंटरॉप के बारे में अनुभाग में, निम्नलिखित भाग ने मेरा ध्यान आकर्षित किया:
वैसे, यह कोड एक और नई सुविधा का उपयोग करता है: अनुक्रमित गुण (श्रेणी के बाद उन चौकोर कोष्ठक पर एक करीब से नज़र डालें।) लेकिन यह सुविधा केवल COM इंटरॉप के लिए उपलब्ध है; आप C # 4.0 में अपने स्वयं के अनुक्रमित गुण नहीं बना सकते ।
ठीक है, लेकिन क्यों ? मुझे पहले से ही पता था और पछतावा था कि C # में अनुक्रमित गुण बनाना संभव नहीं था, लेकिन इस वाक्य ने मुझे इसके बारे में फिर से सोचने पर मजबूर कर दिया। मैं इसे लागू करने के कई अच्छे कारण देख सकता हूं:
- CLR इसका समर्थन करता है (उदाहरण के लिए,
PropertyInfo.GetValue
एकindex
पैरामीटर है), इसलिए यह अफ़सोस की बात है कि हम C # में इसका लाभ नहीं उठा सकते हैं - यह COM इंटरॉप के लिए समर्थित है, जैसा कि लेख में दिखाया गया है (गतिशील प्रेषण का उपयोग करके)
- इसे VB.NET में लागू किया गया है
- इंडेक्सर्स बनाने के लिए पहले से ही, यानी इंडेक्स को ऑब्जेक्ट पर लागू करना संभव है, इसलिए यह विचार को गुणों में विस्तारित करने के लिए कोई बड़ा सौदा नहीं होगा, समान सिंटैक्स रखते हुए और केवल
this
एक संपत्ति के नाम के साथ प्रतिस्थापित करना
यह उस तरह की चीजों को लिखने की अनुमति देगा:
public class Foo
{
private string[] _values = new string[3];
public string Values[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
}
वर्तमान में एकमात्र वर्कअराउंड जो मुझे पता है कि एक आंतरिक वर्ग ( ValuesCollection
उदाहरण के लिए) बनाना है जो एक इंडेक्सर को लागू करता है, और Values
संपत्ति को बदलता है ताकि यह उस आंतरिक वर्ग का एक उदाहरण लौटाए।
यह करना बहुत आसान है, लेकिन कष्टप्रद ... तो शायद कंपाइलर हमारे लिए यह कर सकता है! एक विकल्प एक आंतरिक वर्ग उत्पन्न करना होगा जो सूचकांक को लागू करता है, और इसे एक सार्वजनिक जेनेरिक इंटरफ़ेस के माध्यम से उजागर करता है:
// interface defined in the namespace System
public interface IIndexer<TIndex, TValue>
{
TValue this[TIndex index] { get; set; }
}
public class Foo
{
private string[] _values = new string[3];
private class <>c__DisplayClass1 : IIndexer<int, string>
{
private Foo _foo;
public <>c__DisplayClass1(Foo foo)
{
_foo = foo;
}
public string this[int index]
{
get { return _foo._values[index]; }
set { _foo._values[index] = value; }
}
}
private IIndexer<int, string> <>f__valuesIndexer;
public IIndexer<int, string> Values
{
get
{
if (<>f__valuesIndexer == null)
<>f__valuesIndexer = new <>c__DisplayClass1(this);
return <>f__valuesIndexer;
}
}
}
लेकिन निश्चित रूप से, उस मामले में संपत्ति वास्तव में एक लौटेगी IIndexer<int, string>
, और वास्तव में एक अनुक्रमित संपत्ति नहीं होगी ... एक वास्तविक सीएलआर अनुक्रमित संपत्ति उत्पन्न करना बेहतर होगा।
तुम क्या सोचते हो ? क्या आप इस सुविधा को C # में देखना चाहेंगे? यदि नहीं, तो क्यों?