2012-09-07 15 views
10

out parametresiyle bir Lambda Expression tanımlamak istiyorum. Bunu yapmak mümkün mü?Dışarıda bir ParameterExpression var mı?

Denediğim C# .Net 4.0 konsolu uygulamasından kod parçacıkları aşağıda verilmiştir.

:

sana aynısını yapmaya linq ifadeler kullanmak istediğinizde Ben, ancak, bir çıkış parametresi olan bir temsilci tanımlamak için lambda ifadeleri kullanabilirsiniz Procedure25 görebileceğiniz gibi, prosedür 24'de kod ile başarısız

System.ArgumentException işlenmeyen İleti = ParameterExpression türündeki 'System.Boolean' tip delegesi parametresi için kullanılamaz oldu ben kullanabilirsiniz biliyorum Kaynak = System.Core

'& System.Boolean' bir giriş sınıfı Bir boole üyesi ile ect ve bu şekilde arayanı geri iletmek ama bir şekilde parametreleri tanımlayabilir miyim merak ettim.

Teşekkür

static void Main(string[] args) 
{ 
    Procedure25(); 
    Procedure24(); 
    Console.WriteLine("Done!"); 
    Console.ReadKey(); 
} 

private delegate int Evaluate(string value, out bool usesVars); 

private static void Procedure24() 
{ 

    // This fails to compile: 
    //Expression<Evaluate> x = (string val, out bool usesSimVals) => 
    //{ 
    // usesSimVals = true; 
    // Console.WriteLine(val); 
    // return 1; 
    //}; 


    ParameterExpression valueParameter = Expression.Parameter(typeof (string)); 
    MethodCallExpression methodCall = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }), valueParameter); 

    bool usesVars; 
    ParameterExpression usesVarsParameter = Expression.Parameter(typeof (bool), "out usesVars"); 


    Expression.Lambda<Evaluate>(methodCall, valueParameter, usesVarsParameter).Compile()("test", out usesVars); 
    Console.WriteLine(usesVars); 

} 

private static void Procedure25() 
{ 
    Evaluate x = (string value, out bool vars) => { vars = true; 
    Console.WriteLine(value); 
                return 1; 
    }; 

    bool usesVars; 
    x("test", out usesVars); 
} 

DÜZENLEME:

Ani, harika, teşekkürler. Bu yüzden anahtar şey, MakeByRefType'ı parametre türünde aramaktı. senin kod örneği ek bir sorun var

var usesVarsParameter = Expression.Parameter(typeof(bool).MakeByRefType(), "usesVars"); 

Not: Sen Type.MakeByRefType ihtiyaç

private static void Procedure24() 
{ 
    ParameterExpression valueParameter = Expression.Parameter(typeof (string)); 
    MethodCallExpression methodCall = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }), valueParameter); 

    bool usesVars; 
    ParameterExpression usesVarsParameter = Expression.Parameter(typeof (bool).MakeByRefType(), "out usesVars"); 

    Expression block = Expression.Block(methodCall, Expression.Assign(usesVarsParameter, Expression.Constant(true)), Expression.Constant(1)); 
    int result = Expression.Lambda<Evaluate>(block, valueParameter, usesVarsParameter).Compile()("test", out usesVars); 
    Console.WriteLine("Result={0}, usesVars={1}", result, usesVars); 

} 

cevap

7

: Burada kayıt için

bir kod Ani öneri dayalı çalışır snippet'idir senin anlatım- Gövde doğru değil - delege türünün dönüş türünü tatmin etmek için int döndürmesi gerektiğinde bir değer döndürmüyor.

var body = Expression.Block(methodCall, Expression.Constant(1)); 

Expression.Lambda<Evaluate>(body, valueParameter, usesVarsParameter) 
      .Compile()("test", out usesVars); 

Ayrıca ifadenin içinde out parametre atama edilmemektedir:

İşte (sizin lambda örnekte olduğu gibi) belirlersiniz düzeltebilecek bir yoldur. Expression.Lambda, beklemediğim bir şeyle beklemenize izin veriyor, ancak BCL'nin C# ile aynı kuralları izlemesine gerek yok!

İlgili konular