2008-08-11 20 views
10

मुझे linq के बारे में लगभग कुछ नहीं पता है।वस्तुओं के लिए लिंक - पहली वस्तु का चयन करें

मैं यह कर रहा हूँ:

var apps = from app in Process.GetProcesses() 
    where app.ProcessName.Contains("MyAppName") && app.MainWindowHandle != IntPtr.Zero 
    select app; 

कौन सा मुझे हो जाता है सब चल प्रक्रियाओं जो कि मापदंड से मेल खाने।

लेकिन मुझे नहीं पता कि पहले को कैसे प्राप्त किया जाए। उदाहरण मैं नेट पर पा सकते हैं मैं इस

var matchedApp = (from app in Process.GetProcesses() 
    where app.ProcessName.Contains("MyAppName") && app.MainWindowHandle != IntPtr.Zero 
    select app).First(); 

जो मुझे कुछ हद तक बदसूरत के रूप में हमलों क्या करना है यह सूचित करते हैं लगता है, और यह भी एक अपवाद फेंकता है तो वहाँ कोई मिलता-जुलता प्रक्रियाओं कर रहे हैं। क्या कोई बेहतर तरीका है?

अद्यतन

मैं वास्तव में उस पर SetForegroundWindow

मैं इस समाधान है, जो भी मुझे के रूप में बदसूरत और भयंकर हमलों ले कर आए हैं फोन पहले मिलान के आइटम खोजने की कोशिश कर रहा हूँ, और, लेकिन ऊपर से बेहतर है। कोई विचार?

var unused = from app in Process.GetProcesses() 
    where app.ProcessName.Contains("MyAppName") && app.MainWindowHandle != IntPtr.Zero 
    select SetForegroundWindow(app.MainWindowHandle); // side-effects in linq-query is technically bad I guess 

उत्तर

19

@FryHard FirstOrDefault काम लेकिन याद रखें कि यह शून्य देता है यदि कोई भी पाए जाते हैं जाएगा। इस कोड को परीक्षण किया जाता है नहीं, लेकिन आप क्या चाहते हैं के करीब होना चाहिए:

var app = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.Contains("MyAppName") && p.MainWindowHandle != IntPtr.Zero); 

if (app == null) 
    return; 

SetForegroundWindow(app.MainWindowHandle); 
+0

गिनती के साथ अनावश्यक है, आप इसे एक क्वेरी के रूप में कैसे रखते हैं, न कि एक्सटेंशन विधि? –

+2

@Quintin FirstOrDefault के लिए कोई "कीवर्ड" वाक्यविन्यास नहीं है - आपको एक्सटेंशन विधि का उपयोग करना होगा। –

+1

ठीक है, आप '(क्वेरी) का उपयोग कर सकते हैं। फर्स्टऑर्डडिफॉल्ट()' लेकिन विस्तार विधि प्रेषण इमो –

1

यह मानते हुए कि अपने पहले उदाहरण में ऐप्लिकेशन एक IEnumerable आप एक आइटम है कि आप SetForegroundWindow को भेजना चाहते हैं पाने के लिए .Count और .FirstOrDefault गुण का उपयोग कर सकता है।

var apps = from app in Process.GetProcesses() 
where app.ProcessName.Contains("MyAppName") && app.MainWindowHandle != IntPtr.Zero 
select app; 

if (apps.Count > 0) 
{ 
    SetForegroundWindow(apps.FirstOrDefault().MainWindowHandle); 
} 
+1

जैसा कि कहीं और कहा गया है, यह linq (देरी निष्पादन) के लाभ को हटा देता है और फर्स्टऑरडिफॉल्ट –

2

करो नहीं उपयोग Count() आईसीआर का कहना है की तरह। Count() यह पता लगाने के लिए IEnumerable के माध्यम से कितना आइटम होगा यह पता लगाने के लिए। इस मामले में प्रदर्शन जुर्माना नगण्य हो सकता है क्योंकि कई प्रक्रियाएं नहीं हैं, लेकिन इसमें शामिल होने की एक बुरी आदत है। केवल Count() का उपयोग करें जब आपकी क्वेरी केवल परिणामों की संख्या में रूचि रखती है।Count लगभग कभी भी एक अच्छा विचार नहीं है।

फ़्राहार्ड के उत्तर के साथ कई समस्याएं हैं। सबसे पहले, delayed execution की वजह से, आप परिणामों की संख्या प्राप्त करने के लिए, और एक बार FirstOrDefault प्राप्त करने के लिए, LINQ क्वेरी को दो बार निष्पादित करना समाप्त कर देंगे। दूसरा, गिनती की जांच के बाद FirstOrDefault का उपयोग करने के लिए कोई कारण नहीं है। चूंकि यह शून्य हो सकता है, आपको इसे शून्य के बिना जांचने का कभी भी उपयोग नहीं करना चाहिए। या तो करना apps.First().MainWindowHandle या:

var app = apps.FirstOrDefault(); 

if (app != null) 
    SetForegroundWindow(app.MainWindowHandle); 

यही कारण है कि सबसे अच्छा समाधान मार्क है, प्रश्न के बिना है। जो भी आप चाहते हैं उसे प्राप्त करने के लिए LINQ का उपयोग करने का यह सबसे प्रभावी और स्थिर तरीका है।