के लिए कोई AddRange()
विधि नहीं है IList<T>
।
मैं IList<T>
बिना आइटम के माध्यम से पुनरावृत्ति और Add()
विधि का उपयोग करके वस्तुओं की सूची कैसे जोड़ सकता हूं ?
के लिए कोई AddRange()
विधि नहीं है IList<T>
।
मैं IList<T>
बिना आइटम के माध्यम से पुनरावृत्ति और Add()
विधि का उपयोग करके वस्तुओं की सूची कैसे जोड़ सकता हूं ?
जवाबों:
AddRange
List<T>
इंटरफ़ेस पर नहीं, पर परिभाषित किया गया है।
आप पहुँच प्राप्त करने के लिए List<T>
इसके बजाय चर की घोषणा कर सकते हैं IList<T>
या इसे डाल List<T>
सकते हैं AddRange
।
((List<myType>)myIList).AddRange(anotherList);
इस के रूप में एक, अच्छा अभ्यास (नीचे टिप्पणी देखें) नहीं है IList<T>
हो सकता है नहीं एक हो List<T>
, लेकिन कुछ अन्य प्रकार है कि इंटरफ़ेस कार्यान्वित किया है और बहुत एक नहीं होती AddRange
इस तरह के एक मामले में, आप केवल जब अपने कोड एक फेंकता पता चलेगा - विधि रनटाइम पर अपवाद।
इसलिए, जब तक आप कुछ के लिए नहीं जानते कि प्रकार वास्तव में है जिसे List<T>
आपको उपयोग करने का प्रयास नहीं करना चाहिए AddRange
।
ऐसा करने का एक तरीका ऑपरेटर के रूप में या (सी # 7 के बाद से) के प्रकार का परीक्षण करके है ।
if(myIList is List<T>)
{
// can cast and AddRange
}
else
{
// iterate with Add
}
List<T>
तो आप इस प्रकार के रूप में भी घोषणा कर सकते हैं (या, यदि यह आपके लिए अच्छा विकल्प नहीं है, तो उस स्थान पर कास्ट करें जहां आपको AddRange
इसे स्थानीय रखने की आवश्यकता है - यह बहुत कम लागत वाला ऑपरेशन है ) है।
InvalidCastException
कि List<T>
(उदाहरण के लिए, सरणी) के अलावा किसी और चीज़ पर उपयोग किया जाता है ।
यदि आप सूची के लिए c # स्रोत कोड को देखते हैं , तो मुझे लगता है कि List.AddRange () में अनुकूलन है जो एक साधारण लूप को संबोधित नहीं करता है। इसलिए, एक विस्तार विधि को बस यह देखने के लिए जांचना चाहिए कि क्या आइलिस्ट एक सूची है, और यदि ऐसा है तो अपने मूल AddRange () का उपयोग करें।
स्रोत कोड के आस-पास पोज़ करते हुए आप देखते हैं कि .NET लोग अपने लाइनक एक्सटेंशन में इसी तरह की चीजों को करते हैं जैसे .ToList () (यदि यह एक सूची है, तो इसे कास्ट करें ... अन्यथा इसे बनाएं)।
public static class IListExtension
{
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items)
{
if (list == null) throw new ArgumentNullException(nameof(list));
if (items == null) throw new ArgumentNullException(nameof(items));
if (list is List<T> asList)
{
asList.AddRange(items);
}
else
{
foreach (var item in items)
{
list.Add(item);
}
}
}
}
list
करने के लिए List<T>
दो बार यहां। जिनमें से एक को as
कीवर्ड से दूर रखा जा सकता है ।
if (list is List<T> castedList) { castedList.AddRange(items); }
आप ऐसा कुछ कर सकते हैं:
IList<string> oIList1 = new List<string>{"1","2","3"};
IList<string> oIList2 = new List<string>{"4","5","6"};
IList<string> oIList3 = oIList1.Concat(oIList2).ToList();
तो, मूल रूप से आप Concat()
एक्सटेंशन का उपयोग करेंगे और ToList()
जैसी कार्यक्षमता प्राप्त करेंगे AddRange()
।
Enumerable.Concat
है System.Linq.Enumerable
कि इस पद्धति द्वारा कार्यान्वित किया जाता है और IEnumerable<TSource>
इसलिए मुझे विश्वास है कि इसे वापस नहीं डाला जाना चाहिए IList<TSource>
- यह कार्यान्वयन विवरणों के कारण कुछ और वापस आ सकता है जो हमें स्रोत कोड की जांच के बिना नहीं पता है - हालांकि, इसकी कोई गारंटी नहीं है कि यह परिवर्तित नहीं होगा - इसलिए कई .NET संस्करणों का समर्थन करते समय विशेष ध्यान रखा जाना चाहिए।
आप इस तरह से एक एक्सटेंशन विधि भी लिख सकते हैं:
internal static class EnumerableHelpers
{
public static void AddRange<T>(this IList<T> collection, IEnumerable<T> items)
{
foreach (var item in items)
{
collection.Add(item);
}
}
}
उपयोग:
IList<int> collection = new int[10]; //Or any other IList
var items = new[] {1, 4, 5, 6, 7};
collection.AddRange(items);
जो अभी भी आइटम पर पुनरावृत्ति कर रहा है, लेकिन आपको हर बार कॉल करने पर इसे लिखने या डालने की ज़रूरत नहीं है।
LINQ का उपयोग कर एक और उत्तर, बशर्ते आप जो चीज़ जोड़ रहे हैं वह एक है List<T>
या आप ToList()
उस पर कॉल कर सकते हैं:
IEnumerable<string> toAdd = new string[] {"a", "b", "c"};
IList<string> target = new List<string>();
toAdd.ToList().ForEach(target.Add);
Concat
, जैसा कि @Self_T-0_Programmer ने उत्तर दिया ।