2008-10-16 13 views

उत्तर

12

नहीं, मुझे विश्वास नहीं है।

निश्चित रूप से सी # संकलक इसे अस्वीकार करती है जब एक लैम्ब्डा अभिव्यक्ति परिवर्तित: अभिव्यक्ति पेड़ nexting द्वारा

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

आप शायद इसके चारों ओर काम कर सकता था:

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

यह त्रुटि अर्जित करता है। एक लैम्ब्डा फ़ंक्शन को कॉल करें, जहां असाइनर का मान तर्क है।

11

आपको इसे .NET 4.0 लाइब्रेरी के साथ करने में सक्षम होना चाहिए। अपने .NET 3.5 प्रोजेक्ट में Microsoft.Scripting.Core.dll आयात करके।

मैं डीएलआर 0.9 उपयोग कर रहा हूँ - संस्करण 1.0 में Expession.Block और Expression.Scope पर कुछ बदलाव हो सकता है (आप http://www.codeplex.com/dlr/Thread/View.aspx?ThreadId=43234 से संदर्भ देख सकते हैं)

के बाद नमूना आप को दिखाने के लिए है।

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! 
    } 
} 

तो बस AssignmentExpression.Create() फोन: से पहले नेट 4. यहां इस लापता बिट के आसपास काम करने के लिए की एक और ठोस उदाहरण है

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

के रूप में जॉन स्कीट और TraumaPony पहले से ही कहा है, Expression.Assign उपलब्ध नहीं है Expression.Assign() के स्थान पर।

5

वास्तव में ऐसा करने के लिए मेरे विस्तार विधि:

/// <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

मैं यह काम करने के लिए नहीं कर पा रहे हैं, वहाँ एक संशोधन या ब्लॉग पोस्ट कहीं है? – Maslow

संबंधित मुद्दे