سؤال

لا أعرف شيئًا تقريبًا عن 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
هل كانت مفيدة؟

المحلول

سيعمل @FryHard FirstOrDefault ولكن تذكر أنه يُرجع قيمة فارغة إذا لم يتم العثور على أي شيء.لم يتم اختبار هذا الرمز ولكن يجب أن يكون قريبًا مما تريده:

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

if (app == null)
    return;

SetForegroundWindow(app.MainWindowHandle);

نصائح أخرى

يفعل لا يستخدم Count() كما يقول ICR. Count() سوف تتكرر من خلال IEnumerable لمعرفة عدد العناصر الموجودة فيه.في هذه الحالة، قد تكون عقوبة الأداء ضئيلة نظرًا لعدم وجود العديد من العمليات، لكنها عادة سيئة.فقط استخدم Count() عندما يكون استفسارك مهتمًا فقط بـ عدد النتائج. Count لا تكاد تكون فكرة جيدة على الإطلاق.

هناك العديد من المشاكل في إجابة FryHard.أولا بسبب تأخر التنفيذ, ، سينتهي بك الأمر بتنفيذ استعلام LINQ مرتين، مرة للحصول على عدد النتائج، ومرة ​​للحصول على FirstOrDefault.ثانيا، ليس هناك أي سبب على الإطلاق لاستخدامها FirstOrDefault بعد التحقق من العد.نظرًا لأنه يمكن أن يُرجع قيمة فارغة، فلا يجب عليك أبدًا استخدامها دون التحقق من وجود قيمة فارغة.إما أن تفعل apps.First().MainWindowHandle أو:

var app = apps.FirstOrDefault();

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

هذا هو السبب في أن الحل الأفضل هو حل مارك، بلا شك.إنها الطريقة الأكثر كفاءة واستقرارًا لاستخدام LINQ للحصول على ما تريد.

على افتراض أنه في تطبيقات المثال الأول الخاص بك هو IEnumerable، يمكنك الاستفادة من خصائص .Count و.FirstOrDefault للحصول على العنصر الفردي الذي تريد تمريره إلى SetForegroundWindow.

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 );
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top