क्या एक और उत्तर जोड़ने में कभी देर हो गई है?
मैंने LINQ-to-Objects कोड का एक टन लिखा है और मैं कम से कम उस डोमेन में तर्क देता हूं कि जो भी सरल कोड के लिए उपयोग करता है - जो कि हमेशा डॉट-सिंटैक्स नहीं है, दोनों सिंटैक्स को समझने के लिए अच्छा है।
बेशक कई बार जब डॉट वाक्य रचना कर रहे हैं है जाने का रास्ता - दूसरों इन मामलों में से कई की व्यवस्था की है; हालाँकि, मुझे लगता है कि समझ में कमी आई है - एक बुरा रैप दिया है, यदि आप करेंगे। इसलिए मैं एक नमूना प्रदान करूँगा जहाँ मेरा मानना है कि समझ उपयोगी है।
यहाँ एक अंक प्रतिस्थापन पहेली का हल है: (लिनक्यूपैड का उपयोग करके लिखा गया समाधान, लेकिन कंसोल ऐप में अकेला खड़ा हो सकता है)
// NO
// NO
// NO
//+NO
//===
// OK
var solutions =
from O in Enumerable.Range(1, 8) // 1-9
//.AsQueryable()
from N in Enumerable.Range(1, 8) // 1-9
where O != N
let NO = 10 * N + O
let product = 4 * NO
where product < 100
let K = product % 10
where K != O && K != N && product / 10 == O
select new { N, O, K };
foreach(var i in solutions)
{
Console.WriteLine("N = {0}, O = {1}, K = {2}", i.N, i.O, i.K);
}
//Console.WriteLine("\nsolution expression tree\n" + solutions.Expression);
... जो आउटपुट:
एन = 1, ओ = 6, के = 4
बहुत बुरा नहीं है, तर्क रैखिक रूप से बहता है और हम देख सकते हैं कि यह एक एकल सही समाधान के साथ आता है। यह पहेली हाथ से हल करने के लिए काफी आसान है: तर्क है कि 3>> N
0, और O
> 4 * एन का मतलब है 8> = O
> = 4. 4. इसका मतलब है कि हाथ से परीक्षण करने के लिए अधिकतम 10 मामले हैं (2 के लिए N
-by- 5 के लिए O
)। मैं काफी भटक गया हूं - यह पहेली LINQ चित्रण प्रयोजनों के लिए पेश की गई है।
संकलक रूपांतरण
बहुत सारे कंपाइलर इसे समकक्ष डॉट-सिंटैक्स में अनुवाद करने के लिए करते हैं। सामान्य दूसरे और बाद के from
खंडों को SelectMany
कॉल में बदल दिया जाता है, हमारे पास let
क्लॉस होते हैं जो Select
अनुमानों के साथ कॉल बन जाते हैं, दोनों पारदर्शी-पहचानकर्ता का उपयोग करते हैं । जैसा कि मैं दिखाने वाला हूं, इन पहचानकर्ताओं को डॉट-सिंटैक्स में नाम देना उस दृष्टिकोण की पठनीयता से दूर ले जाता है।
मेरे पास इस कोड को डॉट सिंटैक्स में अनुवाद करने के लिए क्या संकलक है इसे उजागर करने के लिए एक चाल है। यदि आप ऊपर टिप्पणी की गई दो पंक्तियों को जोड़ते हैं और इसे फिर से चलाते हैं, तो आपको निम्न आउटपुट मिलेंगे:
एन = 1, ओ = 6, के = 4
सॉल्यूशन एक्सप्रेशन ट्री सिस्टम .inq.Eumumable + d_ b8.SelectMany (O => रेंज (1, 8), (O, N) => नया <> f _AnonymousType0 2(O = O, N = N)).Where(<>h__TransparentIdentifier0 => (<>h__TransparentIdentifier0.O != <>h__TransparentIdentifier0.N)).Select(<>h__TransparentIdentifier0 => new <>f__AnonymousType1
2 (<> H_ TransparentIdentifier0 = <> h _TransparentIdentifier0, NO = = = ((10 * <> h_ TransparentIdentifier0.N) + <> ज _TransparentIdentifier0.O)))। चुनें (<> h_ TransparentIdentifier1 => नई <> च _AnonymousType2 2(<>h__TransparentIdentifier1 = <>h__TransparentIdentifier1, product = (4 * <>h__TransparentIdentifier1.NO))).Where(<>h__TransparentIdentifier2 => (<>h__TransparentIdentifier2.product < 100)).Select(<>h__TransparentIdentifier2 => new <>f__AnonymousType3
2 (<> h_ TransparentIdentifier2 = <> ज _TransparentIdentifier2, कश्मीर = ( <> h_ TransparentIdentifier2.product 10%)))। कहाँ (<> ज _TransparentIdentifier3 => (((<> h_ TransparentIdentifier3.K! = <> ज _TransparentIdentifier3। <> h_ TransparentIdentifier2। <>h _TransparentIdentifier1। <> h_TransparentIdentifier0.O) andalso (<> ज _TransparentIdentifier3.K! = <> H_ TransparentIdentifier3। <> ज _TransparentIdentifier2। <> H_ TransparentIdentifier1। <> ज _TransparentIdentifier0.N)) andalso ((<> h_ TransparentIdentifier3। <> ज _TransparentIdentifier2। उत्पाद / 10) == <> h_ TransparentIdentifier3। <> ज _TransparentIdentifier2। <> h_ TransparentIdentifier1। <> ज _TransparentIdentifier0.O)))। चुनें (<> h_ TransparentIdentifier3 => नई <> च _AnonymousType4`3 (एन = < > h_ TransparentIdentifier3। <> h _TransparentIdentifier2। <> h_ TransparentIdentifier1। <> h _TransparentIdentifier0.N।O = <> h_ TransparentIdentifier3। <> H_TransparentIdentifier2। <> H_ TransparentIdentifier1। <> H _TransparentIdentifier0.O, K = <> h__TransparentIdentifier3.K)
प्रत्येक LINQ ऑपरेटर को एक नई लाइन पर रखते हुए, "unspeakable" आइडेंटिफायर्स का अनुवाद हम "बोल" कर सकते हैं, अनाम प्रकारों को उनके परिचित रूप में बदल सकते हैं और AndAlso
एक्सप्रेशन-ट्री लिंगो को बदलकर &&
, परिवर्तनों को उजागर करने के लिए कंपाइलर एक समकक्ष पर पहुंच सकते हैं। में डॉट-सिंटैक्स:
var solutions =
Enumerable.Range(1,8) // from O in Enumerable.Range(1,8)
.SelectMany(O => Enumerable.Range(1, 8), (O, N) => new { O = O, N = N }) // from N in Enumerable.Range(1,8)
.Where(temp0 => temp0.O != temp0.N) // where O != N
.Select(temp0 => new { temp0 = temp0, NO = 10 * temp0.N + temp0.O }) // let NO = 10 * N + O
.Select(temp1 => new { temp1 = temp1, product = 4 * temp1.NO }) // let product = 4 * NO
.Where(temp2 => temp2.product < 100) // where product < 100
.Select(temp2 => new { temp2 = temp2, K = temp2.product % 10 }) // let K = product % 10
.Where(temp3 => temp3.K != temp3.temp2.temp1.temp0.O && temp3.K != temp3.temp2.temp1.temp0.N && temp3.temp2.product / 10 == temp3.temp2.temp1.temp0.O)
// where K != O && K != N && product / 10 == O
.Select(temp3 => new { N = temp3.temp2.temp1.temp0.N, O = temp3.temp2.temp1.temp0.O, K = temp3.K });
// select new { N, O, K };
foreach(var i in solutions)
{
Console.WriteLine("N = {0}, O = {1}, K = {2}", i.N, i.O, i.K);
}
यदि आप चलाते हैं तो आप पुष्टि कर सकते हैं कि यह फिर से आउटपुट करता है:
एन = 1, ओ = 6, के = 4
... लेकिन क्या आप कभी इस तरह का कोड लिखेंगे?
मैं जवाब देना चाहता हूँ NONBHN (न केवल नहीं, बल्कि नर्क नहीं!) - क्योंकि यह अभी बहुत जटिल है। यकीन है कि आप "temp0" .. "temp3" की तुलना में कुछ और अधिक सार्थक पहचानकर्ता के साथ आ सकते हैं, लेकिन मुद्दा यह है कि वे कोड में कुछ भी नहीं जोड़ते हैं - वे कोड को बेहतर प्रदर्शन नहीं करते हैं, वे नहीं करते हैं कोड को बेहतर पढ़ें, वे केवल कोड को बदसूरत करते हैं, और यदि आप इसे हाथ से कर रहे हैं, तो इसमें कोई संदेह नहीं है कि आप इसे सही होने से पहले एक या तीन बार गड़बड़ कर देंगे। इसके अलावा, "नाम का खेल" खेलना सार्थक पहचानकर्ताओं के लिए काफी कठिन है, इसलिए मैं नाम-खेल से उस ब्रेक का स्वागत करता हूं जो कंपाइलर मुझे क्वेरी की समझ प्रदान करता है।
आपके लिए गंभीरता से लेने के लिए यह पहेली नमूना वास्तविक रूप से पर्याप्त नहीं हो सकता है ; हालाँकि, अन्य परिदृश्य मौजूद हैं जहाँ क्वेरी समझ चमक है:
- की जटिलता
Join
और GroupJoin
: क्वेरी कॉम्प्रिहेंशन में रेंज वैरिएबल्स की स्कोपिंग उन join
गलतियों को बदल देती है जो कंप्रीहेंशन सिंटैक्स में कंपाइल-टाइम त्रुटियों में अन्यथा डॉट-सिंटैक्स में संकलित हो सकती हैं।
- किसी भी समय कंपाइलर ट्रांसफॉर्मेशन ट्रांसफॉर्मर में एक पारदर्शी-पहचानकर्ता का परिचय देगा, कॉम्प्रिहेंशन सार्थक हो जाएगा। इसमें निम्न में से किसी का उपयोग शामिल है: एकाधिक
from
खंड, join
और join..into
खंड और let
खंड।
मैं अपने गृहनगर में एक से अधिक इंजीनियरिंग की दुकान के बारे में जानता हूं, जिसमें कम्प्रेशन सिंटैक्स है। मुझे लगता है कि यह एक समझदार वाक्य रचना के रूप में एक दया है, लेकिन एक उपकरण और उस पर एक उपयोगी है। मुझे लगता है कि यह कहना बहुत पसंद है, "ऐसी चीजें हैं जो आप एक पेचकश के साथ कर सकते हैं जो आप एक छेनी के साथ नहीं कर सकते। क्योंकि आप छेनी के रूप में एक पेचकश का उपयोग कर सकते हैं, तो राजा के अधीन छेनी पर प्रतिबंध लगा दिया जाता है।"