قائمة C #.تأتي طريقة - كيف يمكنني تمرير قيمة في المسند؟

StackOverflow https://stackoverflow.com/questions/1529846

سؤال

لا أستطيع أن أعمل كيفية القيام ب "البحث" في قائمة كنت استنادا إلى استخدام قيمة سأمرها في وقت التشغيل. إذا رأيت رمزي أدناه، فأنا أريد أن أكون قادرا على العثور على CustomClass في القائمة المعلمة المسبقة التي تساوي x، حيث سيتم تعريف x في وقت التشغيل.

أي أفكار كيفية القيام بمثل هذا البحث في القائمة؟ أو هل هذا غير ممكن دون كتابة مقاومة للماء والقيام بالتجد يدويا؟ في هذه الحالة ربما هناك مجموعة مفاتيح يجب أن ننظر إليها بدلا من ذلك؟

   private List<CustomClass> files;

   public void someMethod()
  {
       Uri u= new Uri(www.test.com);
       CustomClass cc = this.files.find( matchesUri(u) );  // WON'T LET ME DO THIS
  }

   private static bool matchesUri(List<CustomClass> cc, Uri _u)
    {
        return cc.Path == _u;           }


public class CustomClass
{
    private Uri path;

    public Uri Path
    {
        get { return this.path; }
        set { this.path = value; }
    }
}

ملاحظة. يجب أن أعترف أنني لا أتابع الأشياء المسند تماما في Doco في http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx.

هل كانت مفيدة؟

المحلول

استخدام Lambda:

 Uri u = new Uri("www.test.com");
 CustomClass cc = this.files.Find(cc => cc.Path == u);

أو إذا كنت لا تزال ترغب بطريقة مسماة:

static bool matchesUri(CustomClass cc, Uri _u)
{
    return cc.Path == _u;
}

 Uri u = new Uri("www.test.com");
 CustomClass cc = this.files.Find(cc => matchesUri(cc, u));

نصائح أخرى

يمكنك كتابة

CustomClass cc = this.files.Find( p=> p.Path == u );

تتم إرجاع الأسلوب Find () NULL إذا لم يتم العثور على عنصر يطابق المسند.

من أجل اكتمال فقط، إليك ما تفعله إذا كنت لا ترغب في استخدام Lambda:

// Predicate must be a method with a single parameter,
// so we must pass the other parameter in constructor

public class UriMatcher
{
    private readonly Uri _u;
    public UriMatcher(Uri u)
    {
        _u = u;
    }

    // Match is Predicate<CustomClass>
    public bool Match(CustomClass cc)
    {
        return cc.Path == _u;
    }
}

ثم استخدمه كما:

public void someMethod()
{
    Uri u = new Uri("www.test.com");
    UriMatcher matcher = new UriMatcher(u);
    CustomClass cc = this.files.Find(matcher.Match);
}

لاحظ أنك تمر إشارة إلى طريقة, ، وليس نتيجة الطريقة - Match ضد Match().

تحقق هذا الموضوع أيضا: المندوبين المسندين في C #.

public void someMethod()
{
    Uri u= new Uri("www.test.com");
    CustomClass cc = this.files.find( p => { return p.Path == u; } );
}

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

.NET 2.0 الإجابة باستخدام مندوب مجهول (لاحظ أن هذا يعمل فقط ل C #، VB.NET ليس لديه مندوبين مجهولين).

public void someMethod()
{
  Uri u= new Uri("www.test.com");
  CustomClass cc = this.files.find(delegate(CustomClass oTemp) { return oTemp.Path == u;});
}

في Pavel's Post تميز بالجواب، أعتقد أن الخط:

CustomClass cc = this.files.Find(cc => cc.Path == u);

يجب أن يكون بدلا من ذلك:

CustomClass cc = this.files.Find(cc2 => cc2.Path == u);

هذا لأن expresion إلى يسار => هو تعريف متغير (يتم استنتاج النوع من التعبير) - سيعطي المحول البرمجي خطأ إعادة تعريف وإلا خلاف ذلك.

يمكن أيضا كتابة هذا التعبير بتعريف صريح مثل:

CustomClass cc = this.files.Find((CustomClass  cc2) => cc2.Path == u);

هنا هو الحل الذي استخدمته. كنت بحاجة إلى اجتياز العديد من الحجج ولم ترغب في استخدام أي شيء من شأنه أن يمنعني من تحرير الطريقة أثناء وقت التشغيل، لذلك جئت مع هذا.

من الواضح أنه إذا أردت أن تقوم بتغييره إلى طريقة عامة (المصطلح الأيمن؟) باستخدام حجج النوع. هذا أيضا يحصل حول مشكلة لامدراس في طريقة. لست متأكدا مما إذا كان ذلك ينطبق على طرق مجهولة أيضا أم لا، ولكنه منفصل بالفعل حتى لا صفقة كبيرة.

لا أعرف ما إذا كان الانعكاس سيكون له أداء ضرب أم لا.

private Predicate<ItemData> FindItemData(string search, string fieldName)
{
    var field = typeof(ItemData).GetField(fieldName);
    return delegate(ItemData item) { return (string)field.GetValue(item) == search; };
}

//in another method...
itemlist.Find(FindItemData(e.Row[2].ToString(), "ItemName"));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top