"क्विक वॉच" विंडो में डिबगिंग करते समय मैं लैम्बडा एक्सप्रेशन का उपयोग क्यों नहीं कर सकता?
UPD: इसे भी देखें
http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx
"क्विक वॉच" विंडो में डिबगिंग करते समय मैं लैम्बडा एक्सप्रेशन का उपयोग क्यों नहीं कर सकता?
UPD: इसे भी देखें
http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx
जवाबों:
अनाम तरीकों की तरह, लैम्ब्डा अभिव्यक्ति वास्तव में बहुत जटिल जानवर हैं। यहां तक कि अगर हम बाहर Expression
(.NET 3.5) शासन करते हैं , तब भी बहुत अधिक जटिलता छोड़ देता है , न कि कम से कम पकड़े गए चर, जो मूल रूप से उन कोड का पुन: संरचना करते हैं जो उनका उपयोग करते हैं (जैसा कि आप समझते हैं कि चर संकलित-उत्पन्न वर्गों पर फ़ील्ड बन जाते हैं) धुएं और दर्पण के एक बिट के साथ।
इस तरह, मैं कम से कम आश्चर्य में नहीं हूं कि आप उनका उपयोग बेकार में नहीं कर सकते हैं - इस जादू का समर्थन करने वाले बहुत सारे कंपाइलर काम (और पर्दे के पीछे की पीढ़ी) हैं।
नहीं, आप वॉच / लोकल / तत्काल विंडो में लैम्ब्डा एक्सप्रेशन का उपयोग नहीं कर सकते हैं। जैसा कि मार्क ने बताया है कि यह अविश्वसनीय रूप से जटिल है। मैं विषय में थोड़ा और आगे गोता लगाना चाहता था।
डीबगर में एक अनाम फ़ंक्शन को निष्पादित करने के साथ ज्यादातर लोग क्या विचार नहीं करते हैं कि यह एक वैक्यूम में नहीं होता है। अनाम फ़ंक्शन को परिभाषित करने और चलाने का बहुत कार्य कोड आधार की अंतर्निहित संरचना को बदल देता है। कोड को बदलना, सामान्य रूप से, और विशेष रूप से तत्काल खिड़की से, एक बहुत ही मुश्किल काम है।
निम्नलिखित कोड पर विचार करें।
void Example() {
var v1 = 42;
var v2 = 56;
Func<int> func1 = () => v1;
System.Diagnostics.Debugger.Break();
var v3 = v1 + v2;
}
यह विशेष कोड मान v1 पर कब्जा करने के लिए एकल बंद बनाता है। जब भी कोई अनाम फ़ंक्शन इसके दायरे के बाहर घोषित चर का उपयोग करता है, तो क्लोज़र कैप्चर आवश्यक है। सभी इरादों और उद्देश्यों के लिए v1 अब इस फ़ंक्शन में मौजूद नहीं है। अंतिम पंक्ति वास्तव में निम्नलिखित की तरह लगती है
var v3 = closure1.v1 + v2;
यदि फ़ंक्शन उदाहरण डिबगर में चलाया जाता है, तो यह ब्रेक लाइन पर बंद हो जाएगा। अब कल्पना करें कि क्या उपयोगकर्ता ने घड़ी की खिड़की में निम्नलिखित टाइप किया है
(Func<int>)(() => v2);
डीबगर (या अधिक उपयुक्त EE) को ठीक से निष्पादित करने के लिए चर v2 के लिए एक क्लोजर बनाने की आवश्यकता होगी। यह मुश्किल है लेकिन करना असंभव नहीं है।
क्या वास्तव में यह ईई के लिए एक कठिन काम करता है, हालांकि यह अंतिम पंक्ति है। अब उस लाइन को कैसे निष्पादित किया जाना चाहिए? सभी उद्देश्यों और उद्देश्यों के लिए अनाम फ़ंक्शन ने v2 चर को हटा दिया और इसे क्लोजर 2.v2 के साथ बदल दिया। तो कोड की अंतिम पंक्ति वास्तव में अब पढ़ने की जरूरत है
var v3 = closure1.v1 + closure2.v2;
फिर भी वास्तव में कोड में इस प्रभाव को प्राप्त करने के लिए कोड की अंतिम पंक्ति को बदलने के लिए ईई की आवश्यकता होती है जो वास्तव में एक ईएनसी कार्रवाई है। हालांकि यह विशिष्ट उदाहरण संभव है, परिदृश्यों का एक अच्छा हिस्सा नहीं है।
इससे भी बुरी बात यह है कि लैम्बडा एक्सप्रेशन एक नया क्लोजर नहीं बनाना चाहिए। यह वास्तव में मूल बंद करने के लिए डेटा संलग्न होना चाहिए। इस बिंदु पर आप सीधे सीमाओं में प्रवेश करते हैं ENC।
मेरा छोटा उदाहरण दुर्भाग्य से केवल उन समस्याओं की सतह को खरोंचता है जो हम चलाते हैं। मैं कहता हूं कि मैं इस विषय पर एक पूर्ण ब्लॉग पोस्ट लिखूंगा और उम्मीद है कि मेरे पास इस सप्ताहांत का समय होगा।
आप तत्काल या घड़ी की खिड़कियों में लैम्ब्डा के भावों का उपयोग नहीं कर सकते।
आप फिर भी System.Linq। डायनैमिक एक्सप्रेशंस का उपयोग कर सकते हैं , जो फॉर्म को ले जाता है। कहाँ ("Id = @ 0", 2) - इसमें मानक Linq में उपलब्ध तरीकों की पूरी श्रृंखला नहीं है, और पूरी नहीं है मेमने की अभिव्यक्ति की शक्ति, लेकिन फिर भी, यह कुछ भी नहीं से बेहतर है!
.Any(string predicate)
, आप कुछ इस तरह से रख सकते हैं: .Where("Id>2").Any()
वॉच विंडो में, या पिन टू सोर्स। यह बहुत अच्छा है!
भविष्य आ गया है!
लैम्बडा एक्सप्रेशंस को डिबगिंग के लिए समर्थन को विजुअल स्टूडियो 2015 ( लेखन के समय पूर्वावलोकन ) में जोड़ा गया है ।
अभिव्यक्ति के मूल्यांकनकर्ता को फिर से लिखना पड़ा, इसलिए कई विशेषताएं गायब हैं: दूरस्थ डिबगिंग ASP.NET, तत्काल विंडो में चर घोषित करना, गतिशील चर का निरीक्षण करना आदि। लैम्ब्डा अभिव्यक्ति जो मूल कार्यों के लिए कॉल की आवश्यकता होती है वर्तमान में समर्थित नहीं हैं।
यह मदद कर सकता है: विजुअल स्टूडियो के लिए विस्तारित तत्काल विंडो (डिबगिंग में लाइनक, लैम्बडा एक्सप्र का उपयोग करें)
सभी बेहतरीन, पैट्रिक
डीबगर के एक्सप्रेशन मूल्यांकनकर्ता द्वारा लैम्ब्डा एक्सप्रेशंस का समर्थन नहीं किया जाता है ... जो कि संकलन के समय उपयोग किए जाने वाले कंपाइलर्स (या एक्सप्रेशन ट्री) के बजाए, संकलन के समय से शायद ही कोई आश्चर्यचकित करता है (रिफ्लेक्टर में एक नज़र डालें। .NET 2 पर स्विच किए गए डिस्प्ले के साथ उन्हें देख)।
निश्चित रूप से वे संरचना की एक और पूरी परत को बंद कर सकते हैं।
Expression
पेड़ पैदा कर सकते हैं - यह संदर्भ पर निर्भर करता है।
VS 2015 में आप ऐसा कर सकते हैं, यह उनके द्वारा जोड़े गए नए फीचर में से एक है।
यदि आपको अभी भी विजुअल स्टूडियो 2013 का उपयोग करने की आवश्यकता है, तो आप वास्तव में पैकेज विंडो कंसोल विंडो का उपयोग करके तत्काल विंडो में एक लूप, या लैम्ब्डा अभिव्यक्ति लिख सकते हैं। मेरे मामले में, मैंने फ़ंक्शन के शीर्ष पर एक सूची जोड़ी:
private void RemoveRoleHierarchy()
{
#if DEBUG
var departments = _unitOfWork.DepartmentRepository.GetAll().ToList();
var roleHierarchies = _unitOfWork.RoleHierarchyRepository.GetAll().ToList();
#endif
try
{
//RoleHierarchy
foreach (SchoolBo.RoleHierarchy item in _listSoRoleHierarchy.Where(r => r.BusinessKeyMatched == false))
_unitOfWork.RoleHierarchyRepository.Remove(item.Id);
_unitOfWork.Save();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
throw;
}
}
मेरा GetAll()
कार्य कहां है:
private DbSet<T> _dbSet;
public virtual IList<T> GetAll()
{
List<T> list;
IQueryable<T> dbQuery = _dbSet;
list = dbQuery
.ToList<T>();
return list;
}
यहां मुझे निम्न त्रुटि मिलती रही, इसलिए मैं विभिन्न रिपॉजिटरी में सभी वस्तुओं को प्रिंट करना चाहता था:
इनर एक्सेप्शन {"DELETE स्टेटमेंट ने REFERENCE कांस्ट्रेन्ड \" FK_dbo.Depbox_dbo.RoleHierarchy_Oran संगठनात्मक RoleId \ "के साथ विवाद किया। संघर्ष डेटाबेस \" CC_Portal_SchoolObjectModel \ ", टेबल \" dbo.Depolder.Dbox.Dbox.Dbox.Dbox.Dbox/Dbox/Dbox/Dbox/DoD.box/DoD.box/DoD.box/DoD.box/DoD.box/DoD.box/DoD.box/DoD.bd=3Db पर किए गए हैं। बयान समाप्त कर दिया गया है। "} System.Exception {System.Data.SqlClient.SqlException}
फिर, मुझे पता चला कि विभाग के भंडार में कितने रिकॉर्ड हैं, इसे तत्काल विंडो में निष्पादित करके:
_unitOfWork.DepartmentRepository.GetAll().ToList().Count
जो 243 लौटा।
इसलिए, यदि आप पैकेज मैनेजर कंसोल में निम्नलिखित को निष्पादित करते हैं, तो यह सभी मदों को प्रिंट करता है:
PM> for($i = 0; $i -lt 243; $i++) { $a = $dte.Debugger.GetExpression("departments[$i].OrgagnizationalRoleId"); Write-Host $a.Value $i }
आपके प्रश्न का उत्तर देने के लिए, यहां विजुअल स्टूडियो प्रोग्राम मैनेजर की आधिकारिक व्याख्या है कि आप ऐसा क्यों नहीं कर सकते। संक्षेप में, क्योंकि वीएस में लागू करने के लिए "यह वास्तव में, वास्तव में बहुत कठिन है"। लेकिन वर्तमान में यह सुविधा चालू है (जैसा कि 2014 अगस्त को अद्यतन किया गया था)।
डिबगिंग करते समय लंबोदर भावों के मूल्यांकन की अनुमति दें
वहां जाते समय अपना वोट जोड़ें!