2008-10-16 26 views

cevap

12

Hayır, ben buna inanmıyorum. lambda ifadesi dönüştürürken

Kesinlikle C# derleyicisi bunu izin vermiyor: ifade ağaçlar nexting tarafından

CS0832: An expression tree may not contain an assignment operator 
2

Muhtemelen etrafında işe yarayabilir:

int x; 
Expression<Func<int,int>> foo = (x=y); // Assign to x and return value 

Bu hatayı verir. Bir argümanın, devralanın değeri olduğu bir lambda işlevini çağırın.

11

Bunu .NET 4.0 Kitaplığı ile yapabilmeniz gerekir. .NET 3.5 projenize Microsoft.Scripting.Core.dll dosyasını yükleyin.

Ben DLR 0.9 kullanıyorum - sürüm 1.0 Expession.Block ve Expression.Scope üzerinde bozuk para vardır olabilir

izleyerek, örnek göstermek olduğunu (Sen http://www.codeplex.com/dlr/Thread/View.aspx?ThreadId=43234 gelen başvuru görebilirsiniz).

public static class AssignmentExpression 
{ 
    public static Expression Create(Expression left, Expression right) 
    { 
     return 
      Expression.Call(
       null, 
       typeof(AssignmentExpression) 
        .GetMethod("AssignTo", BindingFlags.NonPublic | BindingFlags.Static) 
        .MakeGenericMethod(left.Type), 
       left, 
       right); 
    } 

    private static void AssignTo<T>(ref T left, T right) // note the 'ref', which is 
    {              // important when assigning 
     left = right;          // to value types! 
    } 
} 

Sonra basitçe AssignmentExpression.Create() çağırır: .NET 4. İşte bu eksik bit geçici bir çözüm nasıl başka somut örnek önce

using System; 
using System.Collections.Generic; 
using Microsoft.Scripting.Ast; 
using Microsoft.Linq.Expressions; 
using System.Reflection; 

namespace dlr_sample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Expression> statements = new List<Expression>(); 

      ParameterExpression x = Expression.Variable(typeof(int), "r"); 
      ParameterExpression y = Expression.Variable(typeof(int), "y"); 

      statements.Add(
       Expression.Assign(
        x, 
        Expression.Constant(1) 
       ) 
      ); 

      statements.Add(
       Expression.Assign(
        y, 
        x 
       ) 
      ); 

      MethodInfo cw = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }); 

      statements.Add(
       Expression.Call(
        cw, 
        y 
       ) 
      ); 

      LambdaExpression lambda = Expression.Lambda(Expression.Scope(Expression.Block(statements), x, y)); 

      lambda.Compile().DynamicInvoke(); 
      Console.ReadLine(); 
     } 
    } 
} 
4

Jon Skeet ve TraumaPony önceden değindiğimiz gibi, Expression.Assign kullanılamaz Expression.Assign() yerine.

5

tam yapıyor bunun için My uzatma yöntemi: Bu iş için almak gibi olamaz

/// <summary> 
/// Provides extensions for converting lambda functions into assignment actions 
/// </summary> 
public static class ExpressionExtenstions 
{ 
    /// <summary> 
    /// Converts a field/property retrieve expression into a field/property assign expression 
    /// </summary> 
    /// <typeparam name="TInstance">The type of the instance.</typeparam> 
    /// <typeparam name="TProp">The type of the prop.</typeparam> 
    /// <param name="fieldGetter">The field getter.</param> 
    /// <returns></returns> 
    public static Expression<Action<TInstance, TProp>> ToFieldAssignExpression<TInstance, TProp> 
     (
     this Expression<Func<TInstance, TProp>> fieldGetter 
     ) 
    { 
     if (fieldGetter == null) 
      throw new ArgumentNullException("fieldGetter"); 

     if (fieldGetter.Parameters.Count != 1 || !(fieldGetter.Body is MemberExpression)) 
      throw new ArgumentException(
       @"Input expression must be a single parameter field getter, e.g. g => g._fieldToSet or function(g) g._fieldToSet"); 

     var parms = new[] 
         { 
          fieldGetter.Parameters[0], 
          Expression.Parameter(typeof (TProp), "value") 
         }; 

     Expression body = Expression.Call(AssignmentHelper<TProp>.MethodInfoSetValue, 
              new[] {fieldGetter.Body, parms[1]}); 

     return Expression.Lambda<Action<TInstance, TProp>>(body, parms); 
    } 


    public static Action<TInstance, TProp> ToFieldAssignment<TInstance, TProp> 
     (
     this Expression<Func<TInstance, TProp>> fieldGetter 
     ) 
    { 
     return fieldGetter.ToFieldAssignExpression().Compile(); 
    } 

    #region Nested type: AssignmentHelper 

    private class AssignmentHelper<T> 
    { 
     internal static readonly MethodInfo MethodInfoSetValue = 
      typeof (AssignmentHelper<T>).GetMethod("SetValue", BindingFlags.NonPublic | BindingFlags.Static); 

     private static void SetValue(ref T target, T value) 
     { 
      target = value; 
     } 
    } 

    #endregion 
} 
+0

bir revizyon veya blog yazısı yer var mı? – Maslow

İlgili konular