एकल पैरामीटर से Func <टी> और अभिव्यक्ति <Func <टी >> प्राप्त करें?

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

void Assert(Expression> assertionExpression) {
    if (!assertionExpression.Compile()()) 
    { 
        throw new AssertFailedException(assertionExpression.ToString()); 
    }
}

क्या ऐसा करने का कोई उचित तरीका है?

एक corrolarry के रूप में, सरल संकलक उत्पन्न अभिव्यक्ति पेड़ के मामले में, एक ही उदाहरण हमेशा एक पैरामीटर के रूप में पारित किया जाएगा?

static Dictionary>, Func> cache;

static void Assert(Expression> assertionExpression) {
    Func method = null;
    if (!cache.TryGetValue(assertionExpression, out method)) {
        cache.Add(assertionExpression, method = assertionExpression.Compile());
        Console.WriteLine("cache insert");
    }
    else {
         Console.WriteLine("cache hit");
    }
    if (!method()) 
    { 
        throw new AssertFailedException(assertionExpression.ToString()); 
    }
}

static void someCodeThatExecutesRegularly() {
    Assert(()=>true);
}

public static void Main(string[] args, int argc) 
{
    someCodeThatExecutesRegularly();

    someCodeThatExecutesRegularly();

    someCodeThatExecutesRegularly();
}

आउटपुट 'कैश डालने', कैश हिट ',' कैश हिट 'या' कैश डालने ',' कैश डालने ',' कैश डालने 'होगा।

0
जोड़ा संपादित
विचारों: 1

1 उत्तर

पहले प्रश्न के लिए, आप अभिव्यक्ति के पेड़ को ले सकते हैं और इसे निष्पादन योग्य संस्करण प्राप्त करने के लिए संकलित कर सकते हैं, हालांकि यह हर बार फिर से संकलित होगा ताकि आपको इसे कैश करना पड़े।

static void Assert(Expression> assertionExpression) {
    var func = assertionExpression.Compile();//if you call func() it will execute the expression
}

आपके दूसरे प्रश्न के लिए, यह हर बार एक नया अभिव्यक्ति पेड़ होगा, इसलिए आपको "कैश डालने" "कैश डालने" "कैश डालने" आदि मिलेगा ...

इसे कैश के साथ काम करने और संकलन करने के लिए आप संभवतः फ़ंक्शन के स्ट्रिंग प्रस्तुति को प्राप्त करने के लिए अभिव्यक्ति पर .ToString() का उपयोग कर सकते हैं, लेकिन यदि आपके पास कोई बंद है तो यह बहुत भ्रमित समस्याएं पैदा कर सकता है क्योंकि स्ट्रिंग का प्रतिनिधित्व समान हो सकता है लेकिन बंद चर अलग होंगे, इसलिए यदि आप ऐसा करते हैं, तो देखभाल के साथ उपयोग करें!

0
जोड़ा