Variable.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Variable.cs / 1305376 / Variable.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.Activities 
{
    using System; 
    using System.Activities.Expressions; 
    using System.Activities.Runtime;
    using System.Activities.Validation; 
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Linq.Expressions;
    using System.Runtime; 
    using System.Runtime.Serialization; 

    [DebuggerDisplay("Name = {Name}, Type = {Type}")] 
    public abstract class Variable : LocationReference
    {
        VariableModifiers modifiers;
        string name; 
        int cacheId;
 
        internal Variable() 
            : base()
        { 
            this.Id = -1;
        }

        internal bool IsHandle 
        {
            get; 
            set; 
        }
 
        [DefaultValue(null)]
        public new string Name
        {
            get 
            {
                return this.name; 
            } 
            set
            { 
                this.name = value;
            }
        }
 
        [DefaultValue(VariableModifiers.None)]
        public VariableModifiers Modifiers 
        { 
            get
            { 
                return this.modifiers;
            }
            set
            { 
                VariableModifiersHelper.Validate(value, "value");
                this.modifiers = value; 
            } 
        }
 
        [IgnoreDataMember] // this member is repeated by all subclasses, which we control
        [DefaultValue(null)]
        public ActivityWithResult Default
        { 
            get
            { 
                return this.DefaultCore; 
            }
            set 
            {
                this.DefaultCore = value;
            }
        } 

        protected override string NameCore 
        { 
            get
            { 
                return this.name;
            }
        }
 
        internal abstract ActivityWithResult DefaultCore
        { 
            get; 
            set;
        } 

        internal bool IsPublic
        {
            get; 
            set;
        } 
 
        internal Activity Owner
        { 
            get;
            private set;
        }
 
        internal bool IsInTree
        { 
            get 
            {
                return this.Owner != null; 
            }
        }

        public static Variable Create(string name, Type type, VariableModifiers modifiers) 
        {
            return ActivityUtilities.CreateVariable(name, type, modifiers); 
        } 

        internal bool InitializeRelationship(Activity parent, bool isPublic, ref IList validationErrors) 
        {
            if (this.cacheId == parent.CacheId)
            {
                if (this.Owner != null) 
                {
                    ValidationError validationError = new ValidationError(SR.VariableAlreadyInUseOnActivity(this.Name, parent.DisplayName, this.Owner.DisplayName), false, this.Name, parent); 
                    ActivityUtilities.Add(ref validationErrors, validationError); 

                    // Get out early since we've already initialized this variable. 
                    return false;
                }
            }
 
            this.Owner = parent;
            this.cacheId = parent.CacheId; 
            this.IsPublic = isPublic; 

            if (this.Default != null) 
            {
                ActivityWithResult expression = this.Default;

                if (expression is Argument.IExpressionWrapper) 
                {
                    expression = ((Argument.IExpressionWrapper)expression).InnerExpression; 
                } 

                if (expression.ResultType != this.Type) 
                {
                    ActivityUtilities.Add(
                        ref validationErrors,
                        new ValidationError(SR.VariableExpressionTypeMismatch(this.Name, this.Type, expression.ResultType), false, this.Name, parent)); 
                }
 
                return this.Default.InitializeRelationship(this, isPublic, ref validationErrors); 
            }
 
            return true;
        }

        internal void ThrowIfNotInTree() 
        {
            if (!this.IsInTree) 
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.VariableNotOpen(this.Name, this.Type)));
            } 
        }

        internal void ThrowIfHandle()
        { 
            if (this.IsHandle)
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CannotPerformOperationOnHandle)); 
            }
        } 

        public override Location GetLocation(ActivityContext context)
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context"); 
            } 

            // No need to call context.ThrowIfDisposed explicitly since all 
            // the methods/properties on the context will perform that check.

            ThrowIfNotInTree();
 
            Location location;
            if (!context.AllowChainedEnvironmentAccess) 
            { 
                if (this.IsPublic || !object.ReferenceEquals(this.Owner, context.Activity))
                { 
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.VariableOnlyAccessibleAtScopeOfDeclaration(context.Activity, this.Owner)));
                }

                if (!context.Environment.TryGetLocation(this.Id, out location)) 
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.VariableDoesNotExist(this.Name))); 
                } 
            }
            else 
            {
                // No validations in the allow chained access case

                if (!context.Environment.TryGetLocation(this.Id, this.Owner, out location)) 
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.VariableDoesNotExist(this.Name))); 
                } 
            }
 
            return location;
        }

        // Soft-Link: This method is referenced through reflection by 
        // ExpressionUtilities.TryRewriteLambdaExpression.  Update that
        // file if the signature changes. 
        public object Get(ActivityContext context) 
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context");
            }
 
            return context.GetValue((LocationReference)this);
        } 
 
        public void Set(ActivityContext context, object value)
        { 
            if (context == null)
            {
                throw FxTrace.Exception.ArgumentNull("context");
            } 

            context.SetValue((LocationReference)this, value); 
        } 

        // This method exists for debugger use 
        internal Location InternalGetLocation(LocationEnvironment environment)
        {
            Fx.Assert(this.IsInTree, "Variable must be opened");
 
            Location location;
            if (!environment.TryGetLocation(this.Id, this.Owner, out location)) 
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.VariableDoesNotExist(this.Name)));
            } 
            return location;
        }

        // optional "fast-path" for initial value expressions that can be resolved synchronously 
        internal abstract bool TryPopulateLocation(ActivityExecutor executor, ActivityContext activityContext);
 
        internal abstract Location CreateLocation(); 
    }
 
    public sealed class Variable : Variable
    {
        Activity defaultExpression;
 
        public Variable()
            : base() 
        { 
            this.IsHandle = ActivityUtilities.IsHandle(typeof(T));
        } 

        public Variable(Expression> defaultExpression)
            : this()
        { 
            if (defaultExpression != null)
            { 
                this.Default = new LambdaValue(defaultExpression); 
            }
        } 

        public Variable(string name, Expression> defaultExpression)
            : this(defaultExpression)
        { 
            if (!string.IsNullOrEmpty(name))
            { 
                this.Name = name; 
            }
        } 

        public Variable(string name)
            : this()
        { 
            if (!string.IsNullOrEmpty(name))
            { 
                this.Name = name; 
            }
        } 

        public Variable(string name, T defaultValue)
            : this(name)
        { 
            this.Default = new Literal(defaultValue);
        } 
 
        protected override Type TypeCore
        { 
            get
            {
                return typeof(T);
            } 
        }
 
        [DefaultValue(null)] 
        public new Activity Default
        { 
            get
            {
                return this.defaultExpression;
            } 
            set
            { 
                ThrowIfHandle(); 

                this.defaultExpression = value; 
            }
        }

        internal override ActivityWithResult DefaultCore 
        {
            get 
            { 
                return this.Default;
            } 
            set
            {
                ThrowIfHandle();
 
                if (value == null)
                { 
                    this.defaultExpression = null; 
                    return;
                } 

                if (value is Activity)
                {
                    this.defaultExpression = (Activity)value; 
                }
                else 
                { 
                    this.defaultExpression = new ActivityWithResultWrapper(value);
                } 
            }
        }

        // Soft-Link: This method is referenced through reflection by 
        // ExpressionUtilities.TryRewriteLambdaExpression.  Update that
        // file if the signature changes. 
        public new Location GetLocation(ActivityContext context) 
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context");
            }
 
            return context.GetLocation(this);
        } 
 
        // Soft-Link: This method is referenced through reflection by
        // ExpressionUtilities.TryRewriteLambdaExpression.  Update that 
        // file if the signature changes.
        public new T Get(ActivityContext context)
        {
            if (context == null) 
            {
                throw FxTrace.Exception.ArgumentNull("context"); 
            } 

            return context.GetValue((LocationReference)this); 
        }

        public void Set(ActivityContext context, T value)
        { 
            if (context == null)
            { 
                throw FxTrace.Exception.ArgumentNull("context"); 
            }
 
            context.SetValue((LocationReference)this, value);
        }

        internal override bool TryPopulateLocation(ActivityExecutor executor, ActivityContext activityContext) 
        {
            bool completedSynchronously = true; 
            VariableLocation variableLocation = new VariableLocation(Modifiers, this.IsHandle); 

            if (this.IsHandle) 
            {
                Fx.Assert(this.Default == null, "Default should be null");
                activityContext.Environment.DeclareHandle(this, variableLocation, activityContext.CurrentInstance);
 
                HandleInitializationContext context = new HandleInitializationContext(executor, activityContext.CurrentInstance);
                try 
                { 
                    variableLocation.SetInitialValue((T)context.CreateAndInitializeHandle(typeof(T)));
                } 
                finally
                {
                    context.Dispose();
                } 
            }
            else 
            { 
                activityContext.Environment.Declare(this, variableLocation, activityContext.CurrentInstance);
                if (Default != null) 
                {
                    T value;
                    if (Default.TryGetValue(activityContext, out value))
                    { 
                        variableLocation.SetInitialValue(value);
                    } 
                    else 
                    {
                        variableLocation.SetIsWaitingOnDefaultValue(); 
                        completedSynchronously = false;
                    }
                }
            } 

            return completedSynchronously; 
        } 

        internal override Location CreateLocation() 
        {
            return new VariableLocation(this.Modifiers, this.IsHandle);
        }
 
        [DataContract]
        sealed class VariableLocation : Location, INotifyPropertyChanged 
        { 
            [DataMember(EmitDefaultValue = false)]
            VariableModifiers modifiers; 

            [DataMember(EmitDefaultValue = false)]
            bool isHandle;
 
            [DataMember(EmitDefaultValue = false)]
            bool isWaitingOnDefaultValue; 
 
            PropertyChangedEventHandler propertyChanged;
            NotifyCollectionChangedEventHandler valueCollectionChanged; 
            PropertyChangedEventHandler valuePropertyChanged;

            public VariableLocation(VariableModifiers modifiers, bool isHandle)
                : base() 
            {
                this.modifiers = modifiers; 
                this.isHandle = isHandle; 
            }
 
            public event PropertyChangedEventHandler PropertyChanged
            {
                add
                { 
                    this.propertyChanged += value;
                    INotifyPropertyChanged notifyPropertyChanged = this.Value as INotifyPropertyChanged; 
                    if (notifyPropertyChanged != null) 
                    {
                        notifyPropertyChanged.PropertyChanged += ValuePropertyChangedHandler; 
                    }
                    INotifyCollectionChanged notifyCollectionChanged = this.Value as INotifyCollectionChanged;
                    if (notifyCollectionChanged != null)
                    { 
                        notifyCollectionChanged.CollectionChanged += ValueCollectionChangedHandler;
                    } 
                } 
                remove
                { 
                    this.propertyChanged -= value;
                    INotifyPropertyChanged notifyPropertyChanged = this.Value as INotifyPropertyChanged;
                    if (notifyPropertyChanged != null)
                    { 
                        notifyPropertyChanged.PropertyChanged -= ValuePropertyChangedHandler;
                    } 
                    INotifyCollectionChanged notifyCollectionChanged = this.Value as INotifyCollectionChanged; 
                    if (notifyCollectionChanged != null)
                    { 
                        notifyCollectionChanged.CollectionChanged -= ValueCollectionChangedHandler;
                    }
                }
            } 

            internal override bool CanBeMapped 
            { 
                get
                { 
                    return VariableModifiersHelper.IsMappable(this.modifiers);
                }
            }
 
            public override T Value
            { 
                get 
                {
                    return base.Value; 
                }
                set
                {
                    if (this.isHandle) 
                    {
                        Handle currentValue = base.Value as Handle; 
 
                        // We only allow sets on null or uninitialized handles
                        if (currentValue != null && currentValue.IsInitialized) 
                        {
                            throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CannotPerformOperationOnHandle));
                        }
 
                        // We only allow setting it to null
                        if (value != null) 
                        { 
                            throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CannotPerformOperationOnHandle));
                        } 
                    }

                    if (VariableModifiersHelper.IsReadOnly(this.modifiers))
                    { 
                        if (this.isWaitingOnDefaultValue)
                        { 
                            this.isWaitingOnDefaultValue = false; 
                        }
                        else 
                        {
                            throw FxTrace.Exception.AsError(
                                new InvalidOperationException(SR.ConstVariableCannotBeSet));
                        } 
                    }
 
                    base.Value = value; 
                    NotifyPropertyChanged();
                } 
            }

            NotifyCollectionChangedEventHandler ValueCollectionChangedHandler
            { 
                get
                { 
                    if (this.valueCollectionChanged == null) 
                    {
                        this.valueCollectionChanged = new NotifyCollectionChangedEventHandler(this.NotifyValueCollectionChanged); 
                    }
                    return this.valueCollectionChanged;
                }
            } 

            PropertyChangedEventHandler ValuePropertyChangedHandler 
            { 
                get
                { 
                    if (this.valuePropertyChanged == null)
                    {
                        this.valuePropertyChanged = new PropertyChangedEventHandler(this.NotifyValuePropertyChanged);
                    } 
                    return this.valuePropertyChanged;
                } 
            } 

            internal void SetInitialValue(T value) 
            {
                base.Value = value;
            }
 
            internal void SetIsWaitingOnDefaultValue()
            { 
                if (VariableModifiersHelper.IsReadOnly(this.modifiers)) 
                {
                    this.isWaitingOnDefaultValue = true; 
                }
            }

            void NotifyValueCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
            {
                NotifyPropertyChanged(); 
            } 

            void NotifyValuePropertyChanged(object sender, PropertyChangedEventArgs e) 
            {
                PropertyChangedEventHandler handler = this.propertyChanged;
                if (handler != null)
                { 
                    handler(this, e);
                } 
            } 

            void NotifyPropertyChanged() 
            {
                PropertyChangedEventHandler handler = this.propertyChanged;
                if (handler != null)
                { 
                    handler(this, ActivityUtilities.ValuePropertyChangedEventArgs);
                } 
            } 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

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