विजुअल स्टूडियो डिबगिंग "क्विक वॉच" टूल और लैम्ब्डा एक्सप्रेशन


96

"क्विक वॉच" विंडो में डिबगिंग करते समय मैं लैम्बडा एक्सप्रेशन का उपयोग क्यों नहीं कर सकता?

UPD: इसे भी देखें

http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx

http://blogs.msdn.com/b/jaredpar/archive/2010/06/02/why-is-linq-absent-from-debugger-windows-part-2.aspx


5
यह पूरा हो गया है और वीएस 2015 पूर्वावलोकन में उपलब्ध है। visualstudio.uservoice.com/forums/121579-visual-studio/…
फ्रांसिस्को डी'एनकोनिया


मैंने मेमने की अभिव्यक्ति के लिए MSDN पर दिए गए बहुत सरल उदाहरण की कोशिश की, लेकिन यह काम नहीं करता है। मैं वी.एस. 2015 उद्यम संस्करण है
अदीम

2
@ Franciscod'Anconia को डिबग में लैम्ब्डा सपोर्ट को सक्षम करने के लिए, " मैनेज मैनेजेड कम्पैटिबिलिटी मोड का उपयोग करें" को बंद करना होगा ( stackoverflow.com/a/36559817/818321 ) इसके परिणामस्वरूप, आप सशर्त ब्रेकप्वाइंट का उपयोग नहीं कर पाएंगे: blogs.msdn .microsoft.com / devops / 2013/10/16 / ... और stackoverflow.com/a/35983978/818321
Nik

जवाबों:


64

अनाम तरीकों की तरह, लैम्ब्डा अभिव्यक्ति वास्तव में बहुत जटिल जानवर हैं। यहां तक ​​कि अगर हम बाहर Expression(.NET 3.5) शासन करते हैं , तब भी बहुत अधिक जटिलता छोड़ देता है , न कि कम से कम पकड़े गए चर, जो मूल रूप से उन कोड का पुन: संरचना करते हैं जो उनका उपयोग करते हैं (जैसा कि आप समझते हैं कि चर संकलित-उत्पन्न वर्गों पर फ़ील्ड बन जाते हैं) धुएं और दर्पण के एक बिट के साथ।

इस तरह, मैं कम से कम आश्चर्य में नहीं हूं कि आप उनका उपयोग बेकार में नहीं कर सकते हैं - इस जादू का समर्थन करने वाले बहुत सारे कंपाइलर काम (और पर्दे के पीछे की पीढ़ी) हैं।


91

नहीं, आप वॉच / लोकल / तत्काल विंडो में लैम्ब्डा एक्सप्रेशन का उपयोग नहीं कर सकते हैं। जैसा कि मार्क ने बताया है कि यह अविश्वसनीय रूप से जटिल है। मैं विषय में थोड़ा और आगे गोता लगाना चाहता था।

डीबगर में एक अनाम फ़ंक्शन को निष्पादित करने के साथ ज्यादातर लोग क्या विचार नहीं करते हैं कि यह एक वैक्यूम में नहीं होता है। अनाम फ़ंक्शन को परिभाषित करने और चलाने का बहुत कार्य कोड आधार की अंतर्निहित संरचना को बदल देता है। कोड को बदलना, सामान्य रूप से, और विशेष रूप से तत्काल खिड़की से, एक बहुत ही मुश्किल काम है।

निम्नलिखित कोड पर विचार करें।

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।

मेरा छोटा उदाहरण दुर्भाग्य से केवल उन समस्याओं की सतह को खरोंचता है जो हम चलाते हैं। मैं कहता हूं कि मैं इस विषय पर एक पूर्ण ब्लॉग पोस्ट लिखूंगा और उम्मीद है कि मेरे पास इस सप्ताहांत का समय होगा।


41
Whine, whine, mediocrity, whine, whine स्वीकार करते हैं। डिबगर आईडीई का दिल है, और आपने इसे तोड़ दिया! वॉच विंडो में लंबोदर को कुछ भी कैप्चर करने की आवश्यकता नहीं है। किसी भी अन्य वॉच कोड की तरह, वे केवल विशेष स्टैक फ्रेम पर समझ में आते हैं। (या फिर आप वैरिएबल को कैप्चर करते हैं, उसी वैरिएबल नाम के साथ किसी अन्य फ़ंक्शन में जाते हैं ... और क्या?) डिबगर कंपाइलर के चारों ओर हैक करने के लिए होता है। इसे काम करने लायक बनाओ!
हांग्जो डबलिनस्की

2
वे सरल क्यों घड़ी खिड़की पर भेड़ के बच्चे पर कब्जा कर लिया चर की अनुमति नहीं है। सरल और डिबग परिदृश्यों के एक समूह की अनुमति देगा जहां लैम्बडा का उपयोग वास्तव में कार्यात्मक कोड में किया जा रहा है।
लुइज फेलिप

@LuizFelipe यहां तक ​​कि लेने के तहत अभी भी एक बड़े पैमाने पर है । यह वास्तव में ईई को कॉल बैक (आईएल के लिए सभी तरह) के लिए पूर्ण फ़ंक्शन बॉडी उत्पन्न करने की आवश्यकता है। ईई आज इस प्रकार का कुछ भी नहीं करता है, इसके बजाय यह एक दुभाषिया है।
जरीदपार

1
@JaredPar आप ब्लॉग पोस्ट के बारे में बात करते हुए पोस्ट शेयर कर सकते हैं
एहसान सज्जाद

49

आप तत्काल या घड़ी की खिड़कियों में लैम्ब्डा के भावों का उपयोग नहीं कर सकते।

आप फिर भी System.Linq। डायनैमिक एक्सप्रेशंस का उपयोग कर सकते हैं , जो फॉर्म को ले जाता है। कहाँ ("Id = @ 0", 2) - इसमें मानक Linq में उपलब्ध तरीकों की पूरी श्रृंखला नहीं है, और पूरी नहीं है मेमने की अभिव्यक्ति की शक्ति, लेकिन फिर भी, यह कुछ भी नहीं से बेहतर है!


2
खैर ... जबकि दूसरों ने समझाया जबकि यह संभव नहीं था, यह कम से कम हमें एक संभव समाधान प्रदान करता है। +1
नुलियस

1
बस स्पष्ट करने के लिए, आप "Import System.Linq.Dynamic" और फिर डिबग विंडो में आप '' कहां (कुछ। सक्रिय, "संपत्ति> xyz", कुछ भी नहीं) लिखते हैं
smirkingman

यह भी खूब रही। भले ही आपको लाइनक एक्सटेंशन के तरीकों की पूरी श्रृंखला नहीं मिलती है, जैसे कि नहीं है .Any(string predicate), आप कुछ इस तरह से रख सकते हैं: .Where("Id>2").Any()वॉच विंडो में, या पिन टू सोर्स। यह बहुत अच्छा है!
रक्षक एक

22

भविष्य आ गया है!

लैम्बडा एक्सप्रेशंस को डिबगिंग के लिए समर्थन को विजुअल स्टूडियो 2015 ( लेखन के समय पूर्वावलोकन ) में जोड़ा गया है

अभिव्यक्ति के मूल्यांकनकर्ता को फिर से लिखना पड़ा, इसलिए कई विशेषताएं गायब हैं: दूरस्थ डिबगिंग ASP.NET, तत्काल विंडो में चर घोषित करना, गतिशील चर का निरीक्षण करना आदि। लैम्ब्डा अभिव्यक्ति जो मूल कार्यों के लिए कॉल की आवश्यकता होती है वर्तमान में समर्थित नहीं हैं।


यह देखना अच्छा है। ठंडा...!
राहुल निकेत


5

यह मदद कर सकता है: विजुअल स्टूडियो के लिए विस्तारित तत्काल विंडो (डिबगिंग में लाइनक, लैम्बडा एक्सप्र का उपयोग करें)

सभी बेहतरीन, पैट्रिक


5
ध्यान दें कि जब पहली कड़ी भयानक लग रही है, तो यह अल्फा में है और इसके कभी भी बाहर आने की संभावना नहीं है (आखिरी बार 2008 में अपडेट किया गया)।
जॉन साल्वेटियर

2

डीबगर के एक्सप्रेशन मूल्यांकनकर्ता द्वारा लैम्ब्डा एक्सप्रेशंस का समर्थन नहीं किया जाता है ... जो कि संकलन के समय उपयोग किए जाने वाले कंपाइलर्स (या एक्सप्रेशन ट्री) के बजाए, संकलन के समय से शायद ही कोई आश्चर्यचकित करता है (रिफ्लेक्टर में एक नज़र डालें। .NET 2 पर स्विच किए गए डिस्प्ले के साथ उन्हें देख)।

निश्चित रूप से वे संरचना की एक और पूरी परत को बंद कर सकते हैं।


ठीक है, वे तरीके बना सकते हैं; वे Expressionपेड़ पैदा कर सकते हैं - यह संदर्भ पर निर्भर करता है।
मार्क Gravell

1

VS 2015 में आप ऐसा कर सकते हैं, यह उनके द्वारा जोड़े गए नए फीचर में से एक है।


1

यदि आपको अभी भी विजुअल स्टूडियो 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 }

विचार के लिए लेखक यहां पाया जा सकता है


1

आपके प्रश्न का उत्तर देने के लिए, यहां विजुअल स्टूडियो प्रोग्राम मैनेजर की आधिकारिक व्याख्या है कि आप ऐसा क्यों नहीं कर सकते। संक्षेप में, क्योंकि वीएस में लागू करने के लिए "यह वास्तव में, वास्तव में बहुत कठिन है"। लेकिन वर्तमान में यह सुविधा चालू है (जैसा कि 2014 अगस्त को अद्यतन किया गया था)।

डिबगिंग करते समय लंबोदर भावों के मूल्यांकन की अनुमति दें

वहां जाते समय अपना वोट जोड़ें!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.