MemberInitExpression.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Ast / MemberInitExpression.cs / 1305376 / MemberInitExpression.cs

                            /* **************************************************************************** 
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/ 

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics;
using System.Dynamic.Utils; 
using System.Runtime.CompilerServices;

namespace System.Linq.Expressions {
    ///  
    /// Represents calling a constructor and initializing one or more members of the new object.
    ///  
#if !SILVERLIGHT 
    [DebuggerTypeProxy(typeof(Expression.MemberInitExpressionProxy))]
#endif 
    public sealed class MemberInitExpression : Expression {
        private readonly NewExpression _newExpression;
        private readonly ReadOnlyCollection _bindings;
 
        internal MemberInitExpression(NewExpression newExpression, ReadOnlyCollection bindings) {
            _newExpression = newExpression; 
            _bindings = bindings; 
        }
 
        /// 
        /// Gets the static type of the expression that this  represents.
        /// 
        /// The  that represents the static type of the expression. 
        public sealed override Type Type {
            get { return _newExpression.Type; } 
        } 

        ///  
        /// Gets a value that indicates whether the expression tree node can be reduced.
        /// 
        public override bool CanReduce {
            get { 
                return true;
            } 
        } 

        ///  
        /// Returns the node type of this Expression. Extension nodes should return
        /// ExpressionType.Extension when overriding this method.
        /// 
        /// The  of the expression. 
        public sealed override ExpressionType NodeType {
            get { return ExpressionType.MemberInit; } 
        } 

        ///Gets the expression that represents the constructor call. 
        ///A  that represents the constructor call.
        public NewExpression NewExpression {
            get { return _newExpression; }
        } 

        ///Gets the bindings that describe how to initialize the members of the newly created object. 
        ///A  of  objects which describe how to initialize the members. 
        public ReadOnlyCollection Bindings {
            get { return _bindings; } 
        }

        /// 
        /// Dispatches to the specific visit method for this node type. 
        /// 
        protected internal override Expression Accept(ExpressionVisitor visitor) { 
            return visitor.VisitMemberInit(this); 
        }
 
        /// 
        /// Reduces the  to a simpler expression.
        /// If CanReduce returns true, this should return a valid expression.
        /// This method is allowed to return another node which itself 
        /// must be reduced.
        ///  
        /// The reduced expression. 
        public override Expression Reduce() {
            return ReduceMemberInit(_newExpression, _bindings, true); 
        }

        internal static Expression ReduceMemberInit(Expression objExpression, ReadOnlyCollection bindings, bool keepOnStack) {
            var objVar = Expression.Variable(objExpression.Type, null); 
            int count = bindings.Count;
            var block = new Expression[count + 2]; 
            block[0] = Expression.Assign(objVar, objExpression); 
            for (int i = 0; i < count; i++) {
                block[i + 1] = ReduceMemberBinding(objVar, bindings[i]); 
            }
            block[count + 1] = keepOnStack ? (Expression)objVar : Expression.Empty();
            return Expression.Block(new TrueReadOnlyCollection(block));
        } 

        internal static Expression ReduceListInit(Expression listExpression, ReadOnlyCollection initializers, bool keepOnStack) { 
            var listVar = Expression.Variable(listExpression.Type, null); 
            int count = initializers.Count;
            var block = new Expression[count + 2]; 
            block[0] = Expression.Assign(listVar, listExpression);
            for (int i = 0; i < count; i++) {
                ElementInit element = initializers[i];
                block[i + 1] = Expression.Call(listVar, element.AddMethod, element.Arguments); 
            }
            block[count + 1] = keepOnStack ? (Expression)listVar : Expression.Empty(); 
            return Expression.Block(new TrueReadOnlyCollection(block)); 
        }
 
        internal static Expression ReduceMemberBinding(ParameterExpression objVar, MemberBinding binding) {
            MemberExpression member = Expression.MakeMemberAccess(objVar, binding.Member);
            switch (binding.BindingType) {
                case MemberBindingType.Assignment: 
                    return Expression.Assign(member, ((MemberAssignment)binding).Expression);
                case MemberBindingType.ListBinding: 
                    return ReduceListInit(member, ((MemberListBinding)binding).Initializers, false); 
                case MemberBindingType.MemberBinding:
                    return ReduceMemberInit(member, ((MemberMemberBinding)binding).Bindings, false); 
                default: throw ContractUtils.Unreachable;
            }
        }
 
        /// 
        /// Creates a new expression that is like this one, but using the 
        /// supplied children. If all of the children are the same, it will 
        /// return this expression.
        ///  
        /// The  property of the result.
        /// The  property of the result.
        /// This expression if no children changed, or an expression with the updated children.
        public MemberInitExpression Update(NewExpression newExpression, IEnumerable bindings) { 
            if (newExpression == NewExpression && bindings == Bindings) {
                return this; 
            } 
            return Expression.MemberInit(newExpression, bindings);
        } 
    }

    public partial class Expression {
        ///Creates a . 
        ///A  that has the  property equal to  and the  and  properties set to the specified values.
        ///A  to set the  property equal to. 
        ///An array of  objects to use to populate the  collection. 
        ///
        /// or  is null. 
        ///The  property of an element of  does not represent a member of the type that .Type represents.
        public static MemberInitExpression MemberInit(NewExpression newExpression, params MemberBinding[] bindings) {
            return MemberInit(newExpression, (IEnumerable)bindings);
        } 

        ///Creates a . 
        ///A  that has the  property equal to  and the  and  properties set to the specified values. 
        ///A  to set the  property equal to.
        ///An  that contains  objects to use to populate the  collection. 
        ///
        /// or  is null.
        ///The  property of an element of  does not represent a member of the type that .Type represents.
        public static MemberInitExpression MemberInit(NewExpression newExpression, IEnumerable bindings) { 
            ContractUtils.RequiresNotNull(newExpression, "newExpression");
            ContractUtils.RequiresNotNull(bindings, "bindings"); 
            var roBindings = bindings.ToReadOnly(); 
            ValidateMemberInitArgs(newExpression.Type, roBindings);
            return new MemberInitExpression(newExpression, roBindings); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/* **************************************************************************** 
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/ 

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics;
using System.Dynamic.Utils; 
using System.Runtime.CompilerServices;

namespace System.Linq.Expressions {
    ///  
    /// Represents calling a constructor and initializing one or more members of the new object.
    ///  
#if !SILVERLIGHT 
    [DebuggerTypeProxy(typeof(Expression.MemberInitExpressionProxy))]
#endif 
    public sealed class MemberInitExpression : Expression {
        private readonly NewExpression _newExpression;
        private readonly ReadOnlyCollection _bindings;
 
        internal MemberInitExpression(NewExpression newExpression, ReadOnlyCollection bindings) {
            _newExpression = newExpression; 
            _bindings = bindings; 
        }
 
        /// 
        /// Gets the static type of the expression that this  represents.
        /// 
        /// The  that represents the static type of the expression. 
        public sealed override Type Type {
            get { return _newExpression.Type; } 
        } 

        ///  
        /// Gets a value that indicates whether the expression tree node can be reduced.
        /// 
        public override bool CanReduce {
            get { 
                return true;
            } 
        } 

        ///  
        /// Returns the node type of this Expression. Extension nodes should return
        /// ExpressionType.Extension when overriding this method.
        /// 
        /// The  of the expression. 
        public sealed override ExpressionType NodeType {
            get { return ExpressionType.MemberInit; } 
        } 

        ///Gets the expression that represents the constructor call. 
        ///A  that represents the constructor call.
        public NewExpression NewExpression {
            get { return _newExpression; }
        } 

        ///Gets the bindings that describe how to initialize the members of the newly created object. 
        ///A  of  objects which describe how to initialize the members. 
        public ReadOnlyCollection Bindings {
            get { return _bindings; } 
        }

        /// 
        /// Dispatches to the specific visit method for this node type. 
        /// 
        protected internal override Expression Accept(ExpressionVisitor visitor) { 
            return visitor.VisitMemberInit(this); 
        }
 
        /// 
        /// Reduces the  to a simpler expression.
        /// If CanReduce returns true, this should return a valid expression.
        /// This method is allowed to return another node which itself 
        /// must be reduced.
        ///  
        /// The reduced expression. 
        public override Expression Reduce() {
            return ReduceMemberInit(_newExpression, _bindings, true); 
        }

        internal static Expression ReduceMemberInit(Expression objExpression, ReadOnlyCollection bindings, bool keepOnStack) {
            var objVar = Expression.Variable(objExpression.Type, null); 
            int count = bindings.Count;
            var block = new Expression[count + 2]; 
            block[0] = Expression.Assign(objVar, objExpression); 
            for (int i = 0; i < count; i++) {
                block[i + 1] = ReduceMemberBinding(objVar, bindings[i]); 
            }
            block[count + 1] = keepOnStack ? (Expression)objVar : Expression.Empty();
            return Expression.Block(new TrueReadOnlyCollection(block));
        } 

        internal static Expression ReduceListInit(Expression listExpression, ReadOnlyCollection initializers, bool keepOnStack) { 
            var listVar = Expression.Variable(listExpression.Type, null); 
            int count = initializers.Count;
            var block = new Expression[count + 2]; 
            block[0] = Expression.Assign(listVar, listExpression);
            for (int i = 0; i < count; i++) {
                ElementInit element = initializers[i];
                block[i + 1] = Expression.Call(listVar, element.AddMethod, element.Arguments); 
            }
            block[count + 1] = keepOnStack ? (Expression)listVar : Expression.Empty(); 
            return Expression.Block(new TrueReadOnlyCollection(block)); 
        }
 
        internal static Expression ReduceMemberBinding(ParameterExpression objVar, MemberBinding binding) {
            MemberExpression member = Expression.MakeMemberAccess(objVar, binding.Member);
            switch (binding.BindingType) {
                case MemberBindingType.Assignment: 
                    return Expression.Assign(member, ((MemberAssignment)binding).Expression);
                case MemberBindingType.ListBinding: 
                    return ReduceListInit(member, ((MemberListBinding)binding).Initializers, false); 
                case MemberBindingType.MemberBinding:
                    return ReduceMemberInit(member, ((MemberMemberBinding)binding).Bindings, false); 
                default: throw ContractUtils.Unreachable;
            }
        }
 
        /// 
        /// Creates a new expression that is like this one, but using the 
        /// supplied children. If all of the children are the same, it will 
        /// return this expression.
        ///  
        /// The  property of the result.
        /// The  property of the result.
        /// This expression if no children changed, or an expression with the updated children.
        public MemberInitExpression Update(NewExpression newExpression, IEnumerable bindings) { 
            if (newExpression == NewExpression && bindings == Bindings) {
                return this; 
            } 
            return Expression.MemberInit(newExpression, bindings);
        } 
    }

    public partial class Expression {
        ///Creates a . 
        ///A  that has the  property equal to  and the  and  properties set to the specified values.
        ///A  to set the  property equal to. 
        ///An array of  objects to use to populate the  collection. 
        ///
        /// or  is null. 
        ///The  property of an element of  does not represent a member of the type that .Type represents.
        public static MemberInitExpression MemberInit(NewExpression newExpression, params MemberBinding[] bindings) {
            return MemberInit(newExpression, (IEnumerable)bindings);
        } 

        ///Creates a . 
        ///A  that has the  property equal to  and the  and  properties set to the specified values. 
        ///A  to set the  property equal to.
        ///An  that contains  objects to use to populate the  collection. 
        ///
        /// or  is null.
        ///The  property of an element of  does not represent a member of the type that .Type represents.
        public static MemberInitExpression MemberInit(NewExpression newExpression, IEnumerable bindings) { 
            ContractUtils.RequiresNotNull(newExpression, "newExpression");
            ContractUtils.RequiresNotNull(bindings, "bindings"); 
            var roBindings = bindings.ToReadOnly(); 
            ValidateMemberInitArgs(newExpression.Type, roBindings);
            return new MemberInitExpression(newExpression, roBindings); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK