DependencyProperty.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 / cdf / src / WF / Common / AuthoringOM / DependencyProperty.cs / 1305376 / DependencyProperty.cs

                            #region Using directives 

using System;
using System.Text;
using System.Collections; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.ComponentModel; 
using System.Globalization;
using System.Reflection; 
using System.Runtime.Serialization;
using System.Workflow.ComponentModel.Compiler;
using System.Runtime.CompilerServices;
using System.Security.Permissions; 

#endregion 
 
namespace System.Workflow.ComponentModel
{ 
    //

    [Serializable]
    public sealed class DependencyProperty : ISerializable 
    {
        private static IDictionary dependencyProperties = new Dictionary(); 
 
        internal enum PropertyValidity
        { 
            Uninitialize,
            Reexecute,
            Always
        } 

        class KnownDependencyProperty 
        { 
            internal DependencyProperty dependencyProperty;
            //indicates whether this property, survives beyond Uninitialize. 
            internal PropertyValidity propertyValidity;

            internal KnownDependencyProperty(DependencyProperty dependencyProperty, PropertyValidity propertyValidity)
            { 
                this.dependencyProperty = dependencyProperty;
                this.propertyValidity = propertyValidity; 
            } 
        }
 
        private static KnownDependencyProperty[] knownProperties = new KnownDependencyProperty[256];

        private bool isRegistered = false;
        private string name = String.Empty; 
        private System.Type propertyType = null;
        private System.Type ownerType = null; 
        private System.Type validatorType = null; 
        private PropertyMetadata defaultMetadata = null;
        private byte knownIndex = (byte)0; 
        [NonSerialized]
        private bool isEvent = false;

        public static DependencyProperty Register(string name, System.Type propertyType, System.Type ownerType) 
        {
            return ValidateAndRegister(name, propertyType, ownerType, null, null, true); 
        } 

        public static DependencyProperty Register(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata) 
        {
            return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, true);
        }
 
        public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType)
        { 
            return ValidateAndRegister(name, propertyType, ownerType, null, null, false); 
        }
 
        public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata)
        {
            return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, false);
        } 

        internal static void RegisterAsKnown(DependencyProperty dependencyProperty, byte byteVal, PropertyValidity propertyValidity) 
        { 
            if (dependencyProperty == null)
                throw new ArgumentNullException("dependencyProperty"); 
            if (knownProperties[byteVal] != null)
            {
                throw new InvalidOperationException(SR.GetString(SR.Error_AlreadyRegisteredAs, knownProperties[byteVal].dependencyProperty.ToString()));
            } 

            dependencyProperty.KnownIndex = byteVal; 
            knownProperties[byteVal] = new KnownDependencyProperty(dependencyProperty, propertyValidity); 
        }
 
        internal static DependencyProperty FromKnown(Byte byteVal)
        {
            if (knownProperties[byteVal] == null)
            { 
                throw new InvalidOperationException(SR.GetString(SR.Error_NotRegisteredAs, knownProperties[byteVal].dependencyProperty.ToString()));
            } 
 
            return knownProperties[byteVal].dependencyProperty;
        } 

        //TBD: Dharma - Get rid of this overload
        public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType)
        { 
            if (validatorType == null)
                throw new ArgumentNullException("validatorType"); 
            else if (!typeof(Validator).IsAssignableFrom(validatorType)) 
                throw new ArgumentException(SR.GetString(SR.Error_ValidatorTypeIsInvalid), "validatorType");
 
            return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, validatorType, false);
        }

        public static DependencyProperty FromName(string propertyName, Type ownerType) 
        {
            if (propertyName == null) 
                throw new ArgumentNullException("propertyName"); 

            if (ownerType == null) 
                throw new ArgumentNullException("ownerType");

            DependencyProperty dp = null;
            while ((dp == null) && (ownerType != null)) 
            {
                // Ensure static constructor of type has run 
                RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle); 

                // Locate property 
                int hashCode = propertyName.GetHashCode() ^ ownerType.GetHashCode();
                lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
                {
                    if (DependencyProperty.dependencyProperties.ContainsKey(hashCode)) 
                        dp = DependencyProperty.dependencyProperties[hashCode];
                } 
 
                ownerType = ownerType.BaseType;
            } 

            return dp;
        }
 
        public static IList FromType(Type ownerType)
        { 
            if (ownerType == null) 
                throw new ArgumentNullException("ownerType");
 
            // Ensure static constructor of type has run
            RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);

            List filteredProperties = new List(); 
            lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
            { 
                foreach (DependencyProperty dependencyProperty in DependencyProperty.dependencyProperties.Values) 
                {
                    if (TypeProvider.IsSubclassOf(ownerType, dependencyProperty.ownerType) 
                        || ownerType == dependencyProperty.ownerType)
                        filteredProperties.Add(dependencyProperty);
                }
            } 

            return filteredProperties.AsReadOnly(); 
        } 

        private static DependencyProperty ValidateAndRegister(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType, bool isRegistered) 
        {
            if (name == null)
                throw new ArgumentNullException("name");
 
            if (name.Length == 0)
                throw new ArgumentException(SR.GetString(SR.Error_EmptyArgument), "name"); 
 
            if (propertyType == null)
                throw new ArgumentNullException("propertyType"); 

            if (ownerType == null)
                throw new ArgumentNullException("ownerType");
 
            FieldInfo fieldInfo = null;
            bool isEvent = (typeof(System.Delegate).IsAssignableFrom(propertyType) && (defaultMetadata == null || (defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty) == 0)); 
 
            // WinOE Bug 13807: events can not be meta properties.
            if (isEvent && defaultMetadata != null && defaultMetadata.IsMetaProperty) 
                throw new ArgumentException(SR.GetString(SR.Error_DPAddHandlerMetaProperty), "defaultMetadata");

            //Field must exists
            if (isEvent) 
                fieldInfo = ownerType.GetField(name + "Event", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.GetProperty);
            else 
                fieldInfo = ownerType.GetField(name + "Property", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.GetProperty); 

            if (fieldInfo == null) 
            {
                string error = SR.GetString((isEvent) ? SR.Error_DynamicEventNotSupported : SR.Error_DynamicPropertyNotSupported, new object[] { ownerType.FullName, name });
                throw new ArgumentException(error, "ownerType");
            } 

 
            PropertyMetadata metadata = null; 
            object defaultValue = null;
 
            // Establish default metadata for all types, if none is provided
            if (defaultMetadata == null)
            {
                defaultValue = GetDefaultValue(name, propertyType, ownerType); 
                metadata = new PropertyMetadata(defaultValue);
            } 
            else 
            {
                metadata = defaultMetadata; 
                if (metadata.DefaultValue == null)
                    metadata.DefaultValue = GetDefaultValue(name, propertyType, ownerType);
            }
 
            DependencyProperty dependencyProperty = new DependencyProperty(name, propertyType, ownerType, metadata, validatorType, isRegistered);
            lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot) 
            { 
                if (DependencyProperty.dependencyProperties.ContainsKey(dependencyProperty.GetHashCode()))
                    throw new InvalidOperationException(SR.GetString(SR.Error_DPAlreadyExist, new object[] { name, ownerType.FullName })); 

                DependencyProperty.dependencyProperties.Add(dependencyProperty.GetHashCode(), dependencyProperty);
            }
 
            return dependencyProperty;
        } 
 
        private static object GetDefaultValue(string name, System.Type propertyType, System.Type ownerType)
        { 
            if (name == null)
                throw new ArgumentNullException("name");

            if (name.Length == 0) 
                throw new ArgumentException(SR.GetString(SR.Error_EmptyArgument), "name");
 
            if (propertyType == null) 
                throw new ArgumentNullException("propertyType");
 
            if (ownerType == null)
                throw new ArgumentNullException("ownerType");

            object defaultValue = null; 
            if (propertyType.IsValueType)
            { 
                try 
                {
                    if (propertyType.IsEnum) 
                    {
                        Array values = Enum.GetValues(propertyType);
                        if (values.Length > 0)
                            defaultValue = values.GetValue(0); 
                        else
                            defaultValue = Activator.CreateInstance(propertyType); 
                    } 
                    else
                        defaultValue = Activator.CreateInstance(propertyType); 
                }
                catch
                {
                } 
            }
            return defaultValue; 
        } 

        private DependencyProperty(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType, bool isRegistered) 
        {
            this.name = name;
            this.propertyType = propertyType;
            this.ownerType = ownerType; 
            this.validatorType = validatorType;
            this.isRegistered = isRegistered; 
            this.defaultMetadata = defaultMetadata; 
            this.defaultMetadata.Seal(this, propertyType);
            this.isEvent = (typeof(System.Delegate).IsAssignableFrom(this.propertyType) && (this.defaultMetadata == null || (this.defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty) == 0)); 
        }

        public bool IsEvent
        { 
            get
            { 
                return this.isEvent; 
            }
        } 

        public bool IsAttached
        {
            get 
            {
                return !this.isRegistered; 
            } 
        }
 
        public string Name
        {
            get
            { 
                return this.name;
            } 
        } 

        public System.Type PropertyType 
        {
            get
            {
                return this.propertyType; 
            }
        } 
        public System.Type OwnerType 
        {
            get 
            {
                return this.ownerType;
            }
        } 

        public PropertyMetadata DefaultMetadata 
        { 
            get
            { 
                return this.defaultMetadata;
            }
        }
        public System.Type ValidatorType 
        {
            get 
            { 
                return this.validatorType;
            } 
        }
        internal byte KnownIndex
        {
            get 
            {
                return this.knownIndex; 
            } 
            set
            { 
                this.knownIndex = value;
            }
        }
 
        internal bool IsKnown
        { 
            get 
            {
                return (this.knownIndex != 0); 
            }
        }

        internal PropertyValidity Validity 
        {
            get 
            { 
                return IsKnown ? knownProperties[this.knownIndex].propertyValidity : PropertyValidity.Always;
            } 
        }

        public override string ToString()
        { 
            return this.name;
        } 
 
        public override int GetHashCode()
        { 
            //

            Debug.Assert(this.name != null && this.ownerType != null);
            return (this.name.GetHashCode() ^ this.ownerType.GetHashCode()); 
        }
 
        #region ISerializable Members 

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] 
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("type", this.ownerType);
            info.AddValue("name", this.name); 
            info.SetType(typeof(DependencyPropertyReference));
        } 
        #endregion 

        [Serializable] 
        private sealed class DependencyPropertyReference : IObjectReference
        {
            private Type type = null;
            private string name = null; 

            public Object GetRealObject(StreamingContext context) 
            { 
                return DependencyProperty.FromName(this.name, this.type);
            } 
        }
    }
}

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

using System;
using System.Text;
using System.Collections; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.ComponentModel; 
using System.Globalization;
using System.Reflection; 
using System.Runtime.Serialization;
using System.Workflow.ComponentModel.Compiler;
using System.Runtime.CompilerServices;
using System.Security.Permissions; 

#endregion 
 
namespace System.Workflow.ComponentModel
{ 
    //

    [Serializable]
    public sealed class DependencyProperty : ISerializable 
    {
        private static IDictionary dependencyProperties = new Dictionary(); 
 
        internal enum PropertyValidity
        { 
            Uninitialize,
            Reexecute,
            Always
        } 

        class KnownDependencyProperty 
        { 
            internal DependencyProperty dependencyProperty;
            //indicates whether this property, survives beyond Uninitialize. 
            internal PropertyValidity propertyValidity;

            internal KnownDependencyProperty(DependencyProperty dependencyProperty, PropertyValidity propertyValidity)
            { 
                this.dependencyProperty = dependencyProperty;
                this.propertyValidity = propertyValidity; 
            } 
        }
 
        private static KnownDependencyProperty[] knownProperties = new KnownDependencyProperty[256];

        private bool isRegistered = false;
        private string name = String.Empty; 
        private System.Type propertyType = null;
        private System.Type ownerType = null; 
        private System.Type validatorType = null; 
        private PropertyMetadata defaultMetadata = null;
        private byte knownIndex = (byte)0; 
        [NonSerialized]
        private bool isEvent = false;

        public static DependencyProperty Register(string name, System.Type propertyType, System.Type ownerType) 
        {
            return ValidateAndRegister(name, propertyType, ownerType, null, null, true); 
        } 

        public static DependencyProperty Register(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata) 
        {
            return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, true);
        }
 
        public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType)
        { 
            return ValidateAndRegister(name, propertyType, ownerType, null, null, false); 
        }
 
        public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata)
        {
            return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, false);
        } 

        internal static void RegisterAsKnown(DependencyProperty dependencyProperty, byte byteVal, PropertyValidity propertyValidity) 
        { 
            if (dependencyProperty == null)
                throw new ArgumentNullException("dependencyProperty"); 
            if (knownProperties[byteVal] != null)
            {
                throw new InvalidOperationException(SR.GetString(SR.Error_AlreadyRegisteredAs, knownProperties[byteVal].dependencyProperty.ToString()));
            } 

            dependencyProperty.KnownIndex = byteVal; 
            knownProperties[byteVal] = new KnownDependencyProperty(dependencyProperty, propertyValidity); 
        }
 
        internal static DependencyProperty FromKnown(Byte byteVal)
        {
            if (knownProperties[byteVal] == null)
            { 
                throw new InvalidOperationException(SR.GetString(SR.Error_NotRegisteredAs, knownProperties[byteVal].dependencyProperty.ToString()));
            } 
 
            return knownProperties[byteVal].dependencyProperty;
        } 

        //TBD: Dharma - Get rid of this overload
        public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType)
        { 
            if (validatorType == null)
                throw new ArgumentNullException("validatorType"); 
            else if (!typeof(Validator).IsAssignableFrom(validatorType)) 
                throw new ArgumentException(SR.GetString(SR.Error_ValidatorTypeIsInvalid), "validatorType");
 
            return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, validatorType, false);
        }

        public static DependencyProperty FromName(string propertyName, Type ownerType) 
        {
            if (propertyName == null) 
                throw new ArgumentNullException("propertyName"); 

            if (ownerType == null) 
                throw new ArgumentNullException("ownerType");

            DependencyProperty dp = null;
            while ((dp == null) && (ownerType != null)) 
            {
                // Ensure static constructor of type has run 
                RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle); 

                // Locate property 
                int hashCode = propertyName.GetHashCode() ^ ownerType.GetHashCode();
                lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
                {
                    if (DependencyProperty.dependencyProperties.ContainsKey(hashCode)) 
                        dp = DependencyProperty.dependencyProperties[hashCode];
                } 
 
                ownerType = ownerType.BaseType;
            } 

            return dp;
        }
 
        public static IList FromType(Type ownerType)
        { 
            if (ownerType == null) 
                throw new ArgumentNullException("ownerType");
 
            // Ensure static constructor of type has run
            RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);

            List filteredProperties = new List(); 
            lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
            { 
                foreach (DependencyProperty dependencyProperty in DependencyProperty.dependencyProperties.Values) 
                {
                    if (TypeProvider.IsSubclassOf(ownerType, dependencyProperty.ownerType) 
                        || ownerType == dependencyProperty.ownerType)
                        filteredProperties.Add(dependencyProperty);
                }
            } 

            return filteredProperties.AsReadOnly(); 
        } 

        private static DependencyProperty ValidateAndRegister(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType, bool isRegistered) 
        {
            if (name == null)
                throw new ArgumentNullException("name");
 
            if (name.Length == 0)
                throw new ArgumentException(SR.GetString(SR.Error_EmptyArgument), "name"); 
 
            if (propertyType == null)
                throw new ArgumentNullException("propertyType"); 

            if (ownerType == null)
                throw new ArgumentNullException("ownerType");
 
            FieldInfo fieldInfo = null;
            bool isEvent = (typeof(System.Delegate).IsAssignableFrom(propertyType) && (defaultMetadata == null || (defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty) == 0)); 
 
            // WinOE Bug 13807: events can not be meta properties.
            if (isEvent && defaultMetadata != null && defaultMetadata.IsMetaProperty) 
                throw new ArgumentException(SR.GetString(SR.Error_DPAddHandlerMetaProperty), "defaultMetadata");

            //Field must exists
            if (isEvent) 
                fieldInfo = ownerType.GetField(name + "Event", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.GetProperty);
            else 
                fieldInfo = ownerType.GetField(name + "Property", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.GetProperty); 

            if (fieldInfo == null) 
            {
                string error = SR.GetString((isEvent) ? SR.Error_DynamicEventNotSupported : SR.Error_DynamicPropertyNotSupported, new object[] { ownerType.FullName, name });
                throw new ArgumentException(error, "ownerType");
            } 

 
            PropertyMetadata metadata = null; 
            object defaultValue = null;
 
            // Establish default metadata for all types, if none is provided
            if (defaultMetadata == null)
            {
                defaultValue = GetDefaultValue(name, propertyType, ownerType); 
                metadata = new PropertyMetadata(defaultValue);
            } 
            else 
            {
                metadata = defaultMetadata; 
                if (metadata.DefaultValue == null)
                    metadata.DefaultValue = GetDefaultValue(name, propertyType, ownerType);
            }
 
            DependencyProperty dependencyProperty = new DependencyProperty(name, propertyType, ownerType, metadata, validatorType, isRegistered);
            lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot) 
            { 
                if (DependencyProperty.dependencyProperties.ContainsKey(dependencyProperty.GetHashCode()))
                    throw new InvalidOperationException(SR.GetString(SR.Error_DPAlreadyExist, new object[] { name, ownerType.FullName })); 

                DependencyProperty.dependencyProperties.Add(dependencyProperty.GetHashCode(), dependencyProperty);
            }
 
            return dependencyProperty;
        } 
 
        private static object GetDefaultValue(string name, System.Type propertyType, System.Type ownerType)
        { 
            if (name == null)
                throw new ArgumentNullException("name");

            if (name.Length == 0) 
                throw new ArgumentException(SR.GetString(SR.Error_EmptyArgument), "name");
 
            if (propertyType == null) 
                throw new ArgumentNullException("propertyType");
 
            if (ownerType == null)
                throw new ArgumentNullException("ownerType");

            object defaultValue = null; 
            if (propertyType.IsValueType)
            { 
                try 
                {
                    if (propertyType.IsEnum) 
                    {
                        Array values = Enum.GetValues(propertyType);
                        if (values.Length > 0)
                            defaultValue = values.GetValue(0); 
                        else
                            defaultValue = Activator.CreateInstance(propertyType); 
                    } 
                    else
                        defaultValue = Activator.CreateInstance(propertyType); 
                }
                catch
                {
                } 
            }
            return defaultValue; 
        } 

        private DependencyProperty(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType, bool isRegistered) 
        {
            this.name = name;
            this.propertyType = propertyType;
            this.ownerType = ownerType; 
            this.validatorType = validatorType;
            this.isRegistered = isRegistered; 
            this.defaultMetadata = defaultMetadata; 
            this.defaultMetadata.Seal(this, propertyType);
            this.isEvent = (typeof(System.Delegate).IsAssignableFrom(this.propertyType) && (this.defaultMetadata == null || (this.defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty) == 0)); 
        }

        public bool IsEvent
        { 
            get
            { 
                return this.isEvent; 
            }
        } 

        public bool IsAttached
        {
            get 
            {
                return !this.isRegistered; 
            } 
        }
 
        public string Name
        {
            get
            { 
                return this.name;
            } 
        } 

        public System.Type PropertyType 
        {
            get
            {
                return this.propertyType; 
            }
        } 
        public System.Type OwnerType 
        {
            get 
            {
                return this.ownerType;
            }
        } 

        public PropertyMetadata DefaultMetadata 
        { 
            get
            { 
                return this.defaultMetadata;
            }
        }
        public System.Type ValidatorType 
        {
            get 
            { 
                return this.validatorType;
            } 
        }
        internal byte KnownIndex
        {
            get 
            {
                return this.knownIndex; 
            } 
            set
            { 
                this.knownIndex = value;
            }
        }
 
        internal bool IsKnown
        { 
            get 
            {
                return (this.knownIndex != 0); 
            }
        }

        internal PropertyValidity Validity 
        {
            get 
            { 
                return IsKnown ? knownProperties[this.knownIndex].propertyValidity : PropertyValidity.Always;
            } 
        }

        public override string ToString()
        { 
            return this.name;
        } 
 
        public override int GetHashCode()
        { 
            //

            Debug.Assert(this.name != null && this.ownerType != null);
            return (this.name.GetHashCode() ^ this.ownerType.GetHashCode()); 
        }
 
        #region ISerializable Members 

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] 
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("type", this.ownerType);
            info.AddValue("name", this.name); 
            info.SetType(typeof(DependencyPropertyReference));
        } 
        #endregion 

        [Serializable] 
        private sealed class DependencyPropertyReference : IObjectReference
        {
            private Type type = null;
            private string name = null; 

            public Object GetRealObject(StreamingContext context) 
            { 
                return DependencyProperty.FromName(this.name, this.type);
            } 
        }
    }
}

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