विधि पैरामीटर के रूप में सी # पास लैम्ब्डा अभिव्यक्ति


105

मेरे पास एक लंबोदर अभिव्यक्ति है जिसे मैं चारों ओर से गुजरने और पुन: उपयोग करने में सक्षम होना चाहता हूं। यहाँ कोड है:

public List<IJob> getJobs(/* i want to pass the lambda expr in here */) {
  using (SqlConnection connection = new SqlConnection(getConnectionString())) {
    connection.Open();
    return connection.Query<FullTimeJob, Student, FullTimeJob>(sql, 
      (job, student) => {         
        job.Student = student;
        job.StudentId = student.Id;
        return job;
        },
        splitOn: "user_id",
        param: parameters).ToList<IJob>();   
  }   

यहां कुंजी, क्या मैं लैम्ब्डा अभिव्यक्ति को पास करने में सक्षम होना चाहता हूं जो मैं यहां इस पद्धति का उपयोग कर रहा हूं जो इस कोड को बुला रहा है, इसलिए मैं इसका पुन: उपयोग कर सकता हूं। लैंबडा एक्सप्रेशन मेरे .Query मेथड के अंदर दूसरा तर्क है। मैं मान रहा हूं कि मैं एक एक्शन या फंक का उपयोग करना चाहता हूं, लेकिन मुझे यकीन नहीं है कि इसके लिए सिंटैक्स क्या है या यह कैसे काम करता है। क्या कोई मुझे एक उदाहरण दे सकता है?


3
पैरामीटर को एक क्रिया या एक फंक बनाएं।
मेट्रो स्मर्फ

ठीक है, यही मैंने सोचा था ... क्या आप मुझे एक उदाहरण दिखा सकते हैं कि मैं यह कैसे करूँगा?
एडम लेविट

जवाबों:


122

Func<T1, T2, TResult>पैरामीटर प्रकार के रूप में एक प्रतिनिधि का उपयोग करें और इसे अपने पास करें Query:

public List<IJob> getJobs(Func<FullTimeJob, Student, FullTimeJob> lambda)
{
  using (SqlConnection connection = new SqlConnection(getConnectionString())) {
    connection.Open();
    return connection.Query<FullTimeJob, Student, FullTimeJob>(sql, 
        lambda,
        splitOn: "user_id",
        param: parameters).ToList<IJob>();   
  }  
}

आप इसे कॉल करेंगे:

getJobs((job, student) => {         
        job.Student = student;
        job.StudentId = student.Id;
        return job;
        });

या लैम्बडा को एक वैरिएबल को असाइन करें और इसे पास करें ।


यह बहुत अच्छा लग रहा है, और मैं इस गेटजॉब्स विधि के लैम्ब्डा OUTSIDE को कैसे परिभाषित करूंगा? दूसरे शब्दों में, GetJobs () को लैम्ब्डा को परिभाषित करने के लिए कॉल करने से पहले लाइन क्या है?
एडम लेविट

@AdamLevitt - अपने उदाहरण कोड के साथ एक ही तरीका है। जवाब देने के लिए जोड़ देंगे।
ओडेड

इसके अलावा, फ़ंक्शन पैरामीटर वैसे भी गतिशील हो सकते हैं?
एडम लेविट

@AdamLevitt - आप फ़ंक्शन को सामान्य बना सकते हैं, हालांकि यदि आप लैम्ब्डा पर विभिन्न मापदंडों की संख्या चाहते हैं, तो आपको ओवरलोड की आवश्यकता होगी।
ऊद

सही। जो मैं वास्तव में पसंद करता हूं वह IJob इंटरफ़ेस के विभिन्न कार्यान्वयनों में पारित करने में सक्षम होना है, लेकिन यह डैपर की क्वेरी <> के साथ काम नहीं करेगा क्योंकि इसे चलाने के समय वास्तविक जेनेरिक प्रत्यारोपण वर्ग की आवश्यकता होती है। यह अभी भी बहुत करीब है जो मैं उम्मीद कर रहा था।
एडम लेविट

27

अगर मैं समझता हूं कि आपको निम्नलिखित कोड की आवश्यकता है। (पैरामीटर द्वारा लैम्बडा की अभिव्यक्ति पास करना) विधि

public static void Method(Expression<Func<int, bool>> predicate) { 
    int[] number={1,2,3,4,5,6,7,8,9,10};
    var newList = from x in number
                  .Where(predicate.Compile()) //here compile your clausuly
                  select x;
                newList.ToList();//return a new list
    }

कॉलिंग विधि

Method(v => v.Equals(1));

आप उनकी कक्षा में भी ऐसा कर सकते हैं, देखें यह उदाहरण है।

public string Name {get;set;}

public static List<Class> GetList(Expression<Func<Class, bool>> predicate)
    {
        List<Class> c = new List<Class>();
        c.Add(new Class("name1"));
        c.Add(new Class("name2"));

        var f = from g in c.
                Where (predicate.Compile())
                select g;
        f.ToList();

       return f;
    }

कॉलिंग विधि

Class.GetList(c=>c.Name=="yourname");

मैं उम्मीद करता हूँ यह उपयोगी है


2
क्या आप बता सकते हैं कि हमें इसकी आवश्यकता क्यों Compile()है .Where? मैंने देखा है कि यह भी बिना काम करता है।
Sain17ошƒаӽ

7

लैम्ब्डा अभिव्यक्तियों का एक प्रकार है Action<parameters>(यदि वे कोई मान नहीं लौटाते हैं) या Func<parameters,return>(यदि उनके पास वापसी मान है)। आपके मामले में आपके पास दो इनपुट पैरामीटर हैं, और आपको एक मूल्य वापस करने की आवश्यकता है, इसलिए आपको उपयोग करना चाहिए:

Func<FullTimeJob, Student, FullTimeJob>

5

आपको एक प्रतिनिधि प्रकार का उपयोग करना चाहिए और इसे अपने कमांड पैरामीटर के रूप में निर्दिष्ट करना चाहिए। आप निर्मित प्रतिनिधि प्रकारों में से एक का उपयोग कर सकते हैं - Actionऔर Func

आपके मामले में, ऐसा लगता है कि आपका प्रतिनिधि दो पैरामीटर लेता है, और एक परिणाम देता है, इसलिए आप उपयोग कर सकते हैं Func:

List<IJob> GetJobs(Func<FullTimeJob, Student, FullTimeJob> projection)

फिर आप अपने GetJobsतरीके को एक प्रतिनिधि उदाहरण में पास कर सकते हैं। यह एक तरीका हो सकता है जो उस हस्ताक्षर, एक अनाम प्रतिनिधि या एक लंबोदर अभिव्यक्ति से मेल खाता है।

PS आपको विधि नामों के लिए PascalCase का उपयोग करना चाहिए - GetJobsनहीं getJobs

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