जैसा कि थॉमस बताता है कि एक वस्तु IOrderedEnumerable
हमें बताती है कि इसे किसी भी तरह से आदेश दिया गया है, न कि यह आदेश दिया गया है कि हम इसे बनाए रखना चाहते हैं।
यह भी ध्यान देने योग्य बात है कि वापसी प्रकार ओवरराइड को प्रभावित करने और संकलन की क्षमता होगी, लेकिन चेक के क्रम नहीं लायक है:
private static IOrderedEnumerable<int> ReturnOrdered(){return new int[]{1,2,3}.OrderBy(x => x);}
private static IEnumerable<int> ReturnOrderUnknown(){return ReturnOrdered();}//same object, diff return type.
private static void UseEnumerable(IEnumerable<int> col){Console.WriteLine("Unordered");}
private static void UseEnumerable(IOrderedEnumerable<int> col){Console.WriteLine("Ordered");}
private static void ExamineEnumerable(IEnumerable<int> col)
{
if(col is IOrderedEnumerable<int>)
Console.WriteLine("Enumerable is ordered");
else
Console.WriteLine("Enumerable is unordered");
}
public static void Main(string[] args)
{
//Demonstrate compile-time loses info from return types
//if variable can take either:
var orderUnknown = ReturnOrderUnknown();
UseEnumerable(orderUnknown);//"Unordered";
orderUnknown = ReturnOrdered();
UseEnumerable(orderUnknown);//"Unordered"
//Demonstate this wasn't a bug in the overload selection:
UseEnumerable(ReturnOrdered());//"Ordered"'
//Demonstrate run-time will see "deeper" than the return type anyway:
ExamineEnumerable(ReturnOrderUnknown());//Enumerable is ordered.
}
इस वजह से
, यदि आप एक मामला है जहां या तो IEnumerable<T>
या IOrderedEnumerable<T>
लौटे हो सकता है परिस्थिति के आधार पर कॉलर को, चर को IEnumerable<T>
के रूप में टाइप किया जाएगा और रिटर्न प्रकार की जानकारी खो दी जाएगी। इस बीच, कोई फर्क नहीं पड़ता कि रिटर्न प्रकार क्या है, कॉलर यह निर्धारित करने में सक्षम होगा कि यह प्रकार वास्तव में IOrderedEnumerable<T>
है या नहीं।
किसी भी तरह से, वापसी का प्रकार वास्तव में कोई फर्क नहीं पड़ता।
रिटर्न प्रकारों के साथ व्यापार-बंद कॉलर बनाम कॉलर बनाम लचीलापन के बीच उपयोगिता के बीच है।
वर्तमान में return currentResults.ToList()
के साथ समाप्त होने वाली विधि पर विचार करें।निम्नलिखित वापसी प्रकार संभव हो रहे हैं:
List<T>
IList<T>
ICollection<T>
IEnumerable<T>
IList
ICollection
IEnumerable
object
की वस्तु और गैर सामान्य प्रकार अभी बाहर निकालने के रूप में उपयोगी होने की संभावना नहीं हैं (मामलों में जहां वे उपयोगी होगा में, वे शायद नहीं brainer निर्णय उपयोग करने के लिए कर रहे हैं)। इस पत्ते:
List<T>
IList<T>
ICollection<T>
IEnumerable<T>
सूची हम चले उच्च ऊपर, अधिक सुविधा हम फोन करने वाले उजागर कार्यक्षमता का उपयोग करने के लिए दे उस प्रकार से, यह नीचे दिए गए प्रकार से अवगत नहीं है। हम जिस सूची में जाते हैं, उतनी ही कम लचीलापन हम भविष्य में कार्यान्वयन को बदलने के लिए कैली को अधिक लचीलापन देते हैं। आदर्श रूप में, हम सूची के उच्चतम के रूप में जाना चाहते हैं क्योंकि विधि के उद्देश्य के संदर्भ में समझ में आता है (कॉलर को उपयोगी कार्यक्षमता का पर्दाफाश करने के लिए, और ऐसे मामलों को कम करें जहां नए संग्रह बनाए गए हैं जो हम पहले से ही पेशकश कर रहे थे) लेकिन कोई उच्च नहीं (भविष्य में बदलाव की अनुमति देने के लिए)।
तो, वापस हमारे मामले के लिए जहां हम एक IOrderedEnumerable<TElement>
है कि हम के रूप में वापसी कर सकते हैं या तो एक IOrderedEnumerable<TElement>
या एक IEnumerable<T>
(या IEnumerable
या object
)।
सवाल यह है कि यह वास्तव में विधि के उद्देश्य से संबंधित IOrderedEnumerable
है, या यह केवल एक कार्यान्वयन आर्टेफैक्ट है?
अगर हम था एक विधि ReturnProducts
क्योंकि कॉल करने की परवाह नहीं करनी चाहिए कि यह है कि, कीमत से ऑर्डर करने के लिए के लिए निकालने से मामलों के कार्यान्वयन जहां एक ही उत्पाद अलग-अलग मूल्य के लिए दो बार पेशकश की गई थी के भाग के रूप, तो यह IEnumerable<Product>
लौट जाना हुआ आदेश दिया, और निश्चित रूप से इस पर निर्भर नहीं होना चाहिए।
हम एक विधि ReturnProductsOrderedByPrice
जहां आदेश अपने उद्देश्य का हिस्सा था था, तो हम IOrderedEnumerable<Product>
लौटना चाहिए, क्योंकि इस अपने उद्देश्य के लिए और अधिक बारीकी से संबंधित है, और यथोचित अपेक्षा कर सकते हैं कि केवल बुला CreateOrderedEnumerable
, ThenBy
या ThenByDescending
उस पर (चीजें जो वास्तव में प्रदान करती हैं) और कार्यान्वयन में बाद में बदलाव से यह टूट नहीं गया है।
संपादित करें: मुझे इसका दूसरा भाग याद आया।
इस मामले में एक भंडार क्लॉज द्वारा ऑर्डर द्वारा संग्रहीत प्रक्रिया को लपेटता है। क्या रिपॉजिटरी वापस IOrderedEnumerable वापसी चाहिए? और यह कैसे प्राप्त किया जाएगा?
यह संभव होने पर काफी अच्छा विचार है (या शायद IOrderedQueryable<T>
)। हालांकि, यह आसान नहीं है।
सबसे पहले, आपको यह सुनिश्चित करना होगा कि ORDER BY
के बाद कुछ भी आदेश को पूर्ववत नहीं कर सकता था, यह मामूली नहीं हो सकता है।
दूसरे, आप CreateOrderedEnumerable<TKey>()
के लिए एक कॉल में इस आदेश को वापस नहीं ला करने के लिए है।
उदाहरण के लिए, खेतों A
, B
, C
और D
साथ तत्वों कुछ है कि ORDER BY A DESCENDING, B
इस्तेमाल किया एक प्रकार है कि IOrderedEnumerable<El>
लागू करता MyOrderedEnumerable<El>
कहा जाता है की वापसी में जिसके परिणामस्वरूप से लौटे कर रही है। फिर, तथ्य यह है कि A
और B
वे फ़ील्ड हैं जिन्हें ऑर्डर किया गया था जिन्हें संग्रहीत किया जाना चाहिए। CreateOrderedEnumerable(e => e.D, Comparer<int>.Default, false)
पर कॉल (जो ThenBy
और ThenByDescending
कॉल भी है) उन तत्वों के समूह लेना चाहिए जो समान रूप से A
और B
के लिए समान नियमों के साथ तुलना करते हैं, जिसके लिए वे डेटाबेस द्वारा लौटाए गए थे (डेटाबेस और .NET के बीच मेलिंग मिलान कठिन), और केवल उन समूहों के भीतर यह cmp.Compare(e0.D, e1.D)
के अनुसार आदेश देना चाहिए।
यदि आप ऐसा कर सकते हैं, तो यह बहुत उपयोगी हो सकता है, और यह पूरी तरह उपयुक्त होगा कि IOrderedEnumerable
ORDER BY
क्लॉज सभी कॉलों द्वारा उपयोग किए जाने वाले सभी प्रश्नों पर मौजूद होंगे।
अन्यथा, IOrderedEnumerable
झूठ होगा - क्योंकि आप इसे प्रदान किए गए अनुबंध को पूरा नहीं कर पाएंगे - और यह बेकार से कम होगा।
यह संभव डुप्लिकेट देख http://stackoverflow.com/questions/829487/c-is-it-possible-to-return-an-iorderedenumerablet या http://stackoverflow.com/questions/1783830/can -यह-हो-लाभप्रद के लिए एक-विधि-टू-वापसी-iorderedenumerablet-बजाय के- मैं? RQ = 1 – nawfal