Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / Contract / System / AddIn / Contract / RemoteArgument.cs / 1305376 / RemoteArgument.cs
//------------------------------------------------------------------------------ ////// Copyright (c) Microsoft Corporation. All Rights Reserved. /// Information Contained Herein is Proprietary and Confidential. /// //----------------------------------------------------------------------------- using System; using System.Diagnostics.CodeAnalysis; namespace System.AddIn.Contract { ////// Empty == System.Reflection.Missing /// Intrinsic == All Primitive types, System.String /// public enum RemoteArgumentKind { Missing, Intrinsic, IntrinsicArray, Contract } ////// Similar to the COM Variant type, this class can be used to safely /// pass Contract compliant types through the IRemoteTypeContract /// RemoteArgument passes, by value, the "Convertible" types. /// These are: int, uint, long, ulong, short, ushort, sbyte, byte, char /// decimal, float, double, bool, DateTime, DBNull, Empty and String /// [Serializable] [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")] public struct RemoteArgument { #region Private Fields //this ("value") clearly breaks the rule of "tranistive closure" by //having a field typed as System.Object. We re-enforce the rule //by ensuring the only things that can be assigned here are either //intrinsic types or IContracts, and *never* exposing the object. //This should be the *ONLY* exception, ever, and allows the rule //to be enforced everywhere else private object _value; //byref is changeable, can be set and unset.... private bool isByRef; //the following two fields are "readonly" because once they //are set they are not allowed to change. private readonly RemoteArgumentKind remoteArgKind; private readonly TypeCode intrinsicTypeCode; #endregion #region Static Creation Methods ////// With all the various intrinsic types, in order to avoid each consumer /// of this method having to write the large switch statement to decide which constructor /// to call, we wrote it for you in this helper method. All primitive types /// implement IConvertible, as do enum types, which fit into integral primitives /// String *is* included here though it is not strictly a primitive type. /// Anything with its own type code is included. Anything with TypeCode.Object throws /// /// ///public static RemoteArgument CreateRemoteArgument(object value) { return CreateRemoteArgument(value, false); } /// /// This overload allows the caller to create a byref remote argument /// /// /// ///public static RemoteArgument CreateRemoteArgument(object value, bool isByRef) { if (value == null) throw new ArgumentNullException("value"); System.Array arrayValue = value as System.Array; TypeCode typeCode; if (arrayValue != null) { typeCode = Type.GetTypeCode(arrayValue.GetType().GetElementType()); } else { typeCode = Type.GetTypeCode(value.GetType()); } //else its System.Reflection.Missing, so leave as TypeCode.Empty return CreateRemoteArgument(value, isByRef, typeCode); } /// /// This overload allows the caller to convert between intrinsic types. The returned /// remote argument will contain the type code specified or this will throw. /// /// /// /// ///[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] public static RemoteArgument CreateRemoteArgument(object value, bool isByRef, TypeCode typeCodeToUse) { IConvertible convertibleValue = value as IConvertible; IContract contractValue = value as IContract; System.Array arrayValue = value as System.Array; if ((typeCodeToUse == TypeCode.Object) && (contractValue == null) && (value != null)) { // If the TypeCode is object, we better have a Contract unless the value itself // was null to begin with. In this case, we just want a RemoteArgument for a // null contract. throw new ArgumentException(null, "value"); } else if ((typeCodeToUse == TypeCode.Empty) && (value != System.Reflection.Missing.Value)) { // If the TypeCode is Empty the only valid value is Missing.Value. throw new ArgumentException(null, "value"); } else if ((convertibleValue == null) && (value != null) && (arrayValue == null) && (typeCodeToUse != TypeCode.Object) && (typeCodeToUse != TypeCode.Empty)) { // All the rest of the TypeCodes are for Convertible values, so we better // have one unless of course the value itself was null (i.e. a null string). // In this case, null is completely valid and we should create a null // string RemoteArgument. throw new ArgumentException(null, "value"); } if (arrayValue != null) { TypeCode arrayTypeCode = Type.GetTypeCode(arrayValue.GetType().GetElementType()); if ((arrayTypeCode == TypeCode.Object) || (arrayTypeCode != typeCodeToUse)) throw new ArgumentException(null, "value"); return new RemoteArgument(arrayValue, isByRef); } bool needsConversion = false; if (convertibleValue != null) needsConversion = (convertibleValue.GetTypeCode() != typeCodeToUse); //all of this seemingly duplicated code //is necessary to unbox the value and call the //correct constructor on RemoteArgument switch (typeCodeToUse) { case TypeCode.Boolean: { bool boolToUse; if (needsConversion) boolToUse = convertibleValue.ToBoolean(null); else boolToUse = (bool)convertibleValue; return new RemoteArgument(boolToUse, isByRef); } case TypeCode.Byte: { byte byteToUse; if (needsConversion) byteToUse = convertibleValue.ToByte(null); else byteToUse = (byte)convertibleValue; return new RemoteArgument(byteToUse, isByRef); } case TypeCode.Char: { char charToUse; if (needsConversion) charToUse = convertibleValue.ToChar(null); else charToUse = (char)convertibleValue; return new RemoteArgument(charToUse, isByRef); } case TypeCode.DateTime: { DateTime dateTimeToUse; if (needsConversion) dateTimeToUse = convertibleValue.ToDateTime(null); else dateTimeToUse = (DateTime)convertibleValue; return new RemoteArgument(dateTimeToUse, isByRef); } case TypeCode.DBNull: { //there is no conversion to DBNull //its either DBNull or not, so //throw if needs conversion is true if (needsConversion) throw new NotSupportedException(); return new RemoteArgument((DBNull)convertibleValue); } case TypeCode.Decimal: { decimal decimalToUse; if (needsConversion) decimalToUse = convertibleValue.ToDecimal(null); else decimalToUse = (decimal)convertibleValue; return new RemoteArgument(decimalToUse, isByRef); } case TypeCode.Double: { double doubleToUse; if (needsConversion) doubleToUse = convertibleValue.ToDouble(null); else doubleToUse = (double)convertibleValue; return new RemoteArgument(doubleToUse, isByRef); } case TypeCode.Int16: { short shortToUse; if (needsConversion) shortToUse = convertibleValue.ToInt16(null); else shortToUse = (short)convertibleValue; return new RemoteArgument(shortToUse, isByRef); } case TypeCode.Int32: { int intToUse; if (needsConversion) intToUse = convertibleValue.ToInt32(null); else intToUse = (int)convertibleValue; return new RemoteArgument(intToUse, isByRef); } case TypeCode.Int64: { long longToUse; if (needsConversion) longToUse = convertibleValue.ToInt64(null); else longToUse = (long)convertibleValue; return new RemoteArgument(longToUse, isByRef); } case TypeCode.SByte: { sbyte sbyteToUse; if (needsConversion) sbyteToUse = convertibleValue.ToSByte(null); else sbyteToUse = (sbyte)convertibleValue; return new RemoteArgument(sbyteToUse, isByRef); } case TypeCode.Single: { float floatToUse; if (needsConversion) floatToUse = convertibleValue.ToSingle(null); else floatToUse = (float)convertibleValue; return new RemoteArgument(floatToUse, isByRef); } case TypeCode.String: { string stringToUse; if (needsConversion) stringToUse = convertibleValue.ToString(null); else stringToUse = (string)convertibleValue; return new RemoteArgument(stringToUse, isByRef); } case TypeCode.UInt16: { ushort ushortToUse; if (needsConversion) ushortToUse = convertibleValue.ToUInt16(null); else ushortToUse = (ushort)convertibleValue; return new RemoteArgument(ushortToUse, isByRef); } case TypeCode.UInt32: { uint uintToUse; if (needsConversion) uintToUse = convertibleValue.ToUInt32(null); else uintToUse = (uint)convertibleValue; return new RemoteArgument(uintToUse, isByRef); } case TypeCode.UInt64: { ulong ulongToUse; if (needsConversion) ulongToUse = convertibleValue.ToUInt64(null); else ulongToUse = (ulong)convertibleValue; return new RemoteArgument(ulongToUse, isByRef); } case TypeCode.Empty: { // Just Missing.Value return new RemoteArgument(RemoteArgumentKind.Missing, TypeCode.Empty, isByRef); } case TypeCode.Object: { return new RemoteArgument(contractValue, isByRef); } default: throw new InvalidOperationException(); } } #endregion #region Initializers //the "default constructor" of RemoteArgument is //built-in because this is a struct. //it creates the "Null" RemoteArgument: //value = null; //remoteArgKing = RemoteArgumentKind.Missing //intrinsicTypeCode = TypeCode.Empty #region Contract //Creates the Contract RemoteArgument public RemoteArgument(IContract value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Contract; this.intrinsicTypeCode = TypeCode.Object; this.isByRef = false; } public RemoteArgument(IContract value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Contract; this.intrinsicTypeCode = TypeCode.Object; this.isByRef = isByRef; } #endregion #region Special case for null/"out" params and/or default value intrinsics //isByRef == true means "out". Must be true if Kind == Contract public RemoteArgument(RemoteArgumentKind remoteArgKind, TypeCode typeCode) : this(remoteArgKind, typeCode, false) { } public RemoteArgument(RemoteArgumentKind remoteArgKind, TypeCode typeCode, bool isByRef) { this._value = null; this.isByRef = isByRef; this.remoteArgKind = remoteArgKind; switch (remoteArgKind) { case RemoteArgumentKind.Missing: if (typeCode != TypeCode.Empty) throw new ArgumentException(null, "typeCode"); this.intrinsicTypeCode = typeCode; break; case RemoteArgumentKind.Intrinsic: case RemoteArgumentKind.IntrinsicArray: if (typeCode == TypeCode.Object || typeCode == TypeCode.Empty) throw new ArgumentException(null, "typeCode"); this.intrinsicTypeCode = typeCode; break; case RemoteArgumentKind.Contract: if (typeCode != TypeCode.Object) throw new ArgumentException(null, "typeCode"); this.intrinsicTypeCode = typeCode; break; default: throw new InvalidOperationException(); } } #endregion #region Primitive Types -- CLS Compliant //two for each of the primitive types //value, by ref #region System.Boolean public RemoteArgument(System.Boolean value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Boolean; this.isByRef = false; } public RemoteArgument(System.Boolean value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Boolean; this.isByRef = isByRef; } #endregion #region System.Byte public RemoteArgument(System.Byte value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Byte; this.isByRef = false; } public RemoteArgument(System.Byte value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Byte; this.isByRef = isByRef; } #endregion #region System.Char public RemoteArgument(System.Char value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Char; this.isByRef = false; } public RemoteArgument(System.Char value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Char; this.isByRef = isByRef; } #endregion #region System.DateTime public RemoteArgument(System.DateTime value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DateTime; this.isByRef = false; } public RemoteArgument(System.DateTime value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DateTime; this.isByRef = isByRef; } #endregion #region System.DBNull public RemoteArgument(System.DBNull value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DBNull; this.isByRef = false; } public RemoteArgument(System.DBNull value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DBNull; this.isByRef = isByRef; } #endregion #region System.Decimal public RemoteArgument(System.Decimal value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Decimal; this.isByRef = false; } public RemoteArgument(System.Decimal value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Decimal; this.isByRef = isByRef; } #endregion #region System.Double public RemoteArgument(System.Double value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Double; this.isByRef = false; } public RemoteArgument(System.Double value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Double; this.isByRef = isByRef; } #endregion #region System.Int16 public RemoteArgument(System.Int16 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int16; this.isByRef = false; } public RemoteArgument(System.Int16 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int16; this.isByRef = isByRef; } #endregion #region System.Int32 public RemoteArgument(System.Int32 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int32; this.isByRef = false; } public RemoteArgument(System.Int32 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int32; this.isByRef = isByRef; } #endregion #region System.Int64 public RemoteArgument(System.Int64 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int64; this.isByRef = false; } public RemoteArgument(System.Int64 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int64; this.isByRef = isByRef; } #endregion #region System.Single public RemoteArgument(System.Single value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Single; this.isByRef = false; } public RemoteArgument(System.Single value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Single; this.isByRef = isByRef; } #endregion #region System.String public RemoteArgument(System.String value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.String; this.isByRef = false; } public RemoteArgument(System.String value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.String; this.isByRef = isByRef; } #endregion #endregion #region Intrinsic Types Non-CLS Compliant #region System.SByte [CLSCompliant(false)] public RemoteArgument(System.SByte value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.SByte; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.SByte value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.SByte; this.isByRef = isByRef; } #endregion #region System.UInt16 [CLSCompliant(false)] public RemoteArgument(System.UInt16 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt16; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.UInt16 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt16; this.isByRef = isByRef; } #endregion #region System.UInt32 [CLSCompliant(false)] public RemoteArgument(System.UInt32 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt32; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.UInt32 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt32; this.isByRef = isByRef; } #endregion #region System.UInt64 [CLSCompliant(false)] public RemoteArgument(System.UInt64 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt64; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.UInt64 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt64; this.isByRef = isByRef; } #endregion #endregion #region IntrinsicArray //we could have overloads for each of the primitive //type arrays, but arrays can be multidimensional //so we'd need this as a catchall anyway. //So this throws if the array element type isn't intrinsic //NOTE we don't support System.Reflection.Missing[] //makes no sense.... public RemoteArgument(System.Array array) { if (array == null) { throw new ArgumentNullException("array"); } //this handles multi-dimensional intrinsic arrays, too. //Jagged arrays are handled recursively as arrays of arrays //we can't just ask the type if it IsPrimitive because string says "false" if (Type.GetTypeCode(array.GetType().GetElementType()) == TypeCode.Object) { throw new ArgumentException(null, "array"); } this._value = array; this.remoteArgKind = RemoteArgumentKind.IntrinsicArray; //for IntrinsicArray this holds the element type code this.intrinsicTypeCode = Type.GetTypeCode(array.GetType().GetElementType()); this.isByRef = false; } public RemoteArgument(System.Array array, bool isByRef) { if (array == null) { throw new ArgumentNullException("array"); } //this handles multi-dimensional intrinsic arrays, too. //Jagged arrays are handled recursively as arrays of arrays //we can't just ask the type if it IsPrimitive because string says "false" if (Type.GetTypeCode(array.GetType().GetElementType()) == TypeCode.Object) { throw new ArgumentException(null, "array"); } this._value = array; this.remoteArgKind = RemoteArgumentKind.IntrinsicArray; //for IntrinsicArray this holds the element type code this.intrinsicTypeCode = Type.GetTypeCode(array.GetType().GetElementType()); this.isByRef = isByRef; } #endregion #endregion #region Public Accessors public RemoteArgumentKind RemoteArgumentKind { get { return this.remoteArgKind; } } public TypeCode TypeCode { get { return this.intrinsicTypeCode; } } public bool IsByRef { get { return this.isByRef; } set { this.isByRef = value; } } #region Type Specific Value Properties /// /// All of these properties do the same thing: /// On get, validate return and typecode, return if /// appropriate, else throw InvalidOperationException /// On set, isByRef MUST be true, then validate kind /// and typecode and set value if appropriate, else /// throw InvalidOperationException /// #region Contract public IContract ContractValue { get { if (this.remoteArgKind == RemoteArgumentKind.Contract && this.intrinsicTypeCode == TypeCode.Object) { //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (IContract)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Contract && this.intrinsicTypeCode == TypeCode.Object) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Reflection.Missing public System.Reflection.Missing MissingValue { get { if (this.remoteArgKind == RemoteArgumentKind.Missing && this.intrinsicTypeCode == TypeCode.Empty) { //only one possible return value... return System.Reflection.Missing.Value; } throw new InvalidOperationException(); } } #endregion #region Primitive Types -- CLS Compliant ////// A Note on the implementation: We could have used /// a generic helper function to eliminate so much duplicated /// code. We chose not to to avoid misuse of the generic argument /// Explicitly coding all of these leaves nothing to interpretation /// on the use of a function. /// #region System.Boolean public System.Boolean BooleanValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Boolean) { if (this._value == null) return default(System.Boolean); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Boolean)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Boolean) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Byte public System.Byte ByteValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Byte) { if (this._value == null) return default(System.Byte); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Byte)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Byte) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Char public System.Char CharValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Char) { if (this._value == null) return default(System.Char); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Char)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Char) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.DateTime public System.DateTime DateTimeValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DateTime) { if (this._value == null) return default(System.DateTime); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.DateTime)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DateTime) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.DBNull public System.DBNull DBNullValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DBNull) { if (this._value == null) return default(System.DBNull); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.DBNull)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DBNull) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Decimal public System.Decimal DecimalValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Decimal) { if (this._value == null) return default(System.Decimal); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Decimal)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Decimal) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Double public System.Double DoubleValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Double) { if (this._value == null) return default(System.Double); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Double)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Double) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Int16 public System.Int16 Int16Value { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int16) { if (this._value == null) return default(System.Int16); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Int16)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int16) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Int32 public System.Int32 Int32Value { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int32) { if (this._value == null) return default(System.Int32); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Int32)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int32) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Int64 public System.Int64 Int64Value { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int64) { if (this._value == null) return default(System.Int64); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Int64)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int64) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Single public System.Single SingleValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Single) { if (this._value == null) return default(System.Single); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Single)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Single) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.String public System.String StringValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.String) { if (this._value == null) return default(System.String); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.String)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.String) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #endregion #region Intrinsic Types -- Non-CLS Compliant #region System.SByte [CLSCompliant(false)] public System.SByte SByteValue { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.SByte) { if (this._value == null) return default(System.SByte); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.SByte)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.SByte) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.UInt16 [CLSCompliant(false)] public System.UInt16 UInt16Value { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt16) { if (this._value == null) return default(System.UInt16); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.UInt16)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt16) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.UInt32 [CLSCompliant(false)] public System.UInt32 UInt32Value { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt32) { if (this._value == null) return default(System.UInt32); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.UInt32)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt32) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.UInt64 [CLSCompliant(false)] public System.UInt64 UInt64Value { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt64) { if (this._value == null) return default(System.UInt64); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.UInt64)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt64) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #endregion #region IntrinsicArray [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public System.Array ArrayValue { get { if (this.remoteArgKind == RemoteArgumentKind.IntrinsicArray && this.intrinsicTypeCode != TypeCode.Object) { //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Array)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.IntrinsicArray && this.intrinsicTypeCode != TypeCode.Object) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ ////// Copyright (c) Microsoft Corporation. All Rights Reserved. /// Information Contained Herein is Proprietary and Confidential. /// //----------------------------------------------------------------------------- using System; using System.Diagnostics.CodeAnalysis; namespace System.AddIn.Contract { ////// Empty == System.Reflection.Missing /// Intrinsic == All Primitive types, System.String /// public enum RemoteArgumentKind { Missing, Intrinsic, IntrinsicArray, Contract } ////// Similar to the COM Variant type, this class can be used to safely /// pass Contract compliant types through the IRemoteTypeContract /// RemoteArgument passes, by value, the "Convertible" types. /// These are: int, uint, long, ulong, short, ushort, sbyte, byte, char /// decimal, float, double, bool, DateTime, DBNull, Empty and String /// [Serializable] [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")] public struct RemoteArgument { #region Private Fields //this ("value") clearly breaks the rule of "tranistive closure" by //having a field typed as System.Object. We re-enforce the rule //by ensuring the only things that can be assigned here are either //intrinsic types or IContracts, and *never* exposing the object. //This should be the *ONLY* exception, ever, and allows the rule //to be enforced everywhere else private object _value; //byref is changeable, can be set and unset.... private bool isByRef; //the following two fields are "readonly" because once they //are set they are not allowed to change. private readonly RemoteArgumentKind remoteArgKind; private readonly TypeCode intrinsicTypeCode; #endregion #region Static Creation Methods ////// With all the various intrinsic types, in order to avoid each consumer /// of this method having to write the large switch statement to decide which constructor /// to call, we wrote it for you in this helper method. All primitive types /// implement IConvertible, as do enum types, which fit into integral primitives /// String *is* included here though it is not strictly a primitive type. /// Anything with its own type code is included. Anything with TypeCode.Object throws /// /// ///public static RemoteArgument CreateRemoteArgument(object value) { return CreateRemoteArgument(value, false); } /// /// This overload allows the caller to create a byref remote argument /// /// /// ///public static RemoteArgument CreateRemoteArgument(object value, bool isByRef) { if (value == null) throw new ArgumentNullException("value"); System.Array arrayValue = value as System.Array; TypeCode typeCode; if (arrayValue != null) { typeCode = Type.GetTypeCode(arrayValue.GetType().GetElementType()); } else { typeCode = Type.GetTypeCode(value.GetType()); } //else its System.Reflection.Missing, so leave as TypeCode.Empty return CreateRemoteArgument(value, isByRef, typeCode); } /// /// This overload allows the caller to convert between intrinsic types. The returned /// remote argument will contain the type code specified or this will throw. /// /// /// /// ///[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] public static RemoteArgument CreateRemoteArgument(object value, bool isByRef, TypeCode typeCodeToUse) { IConvertible convertibleValue = value as IConvertible; IContract contractValue = value as IContract; System.Array arrayValue = value as System.Array; if ((typeCodeToUse == TypeCode.Object) && (contractValue == null) && (value != null)) { // If the TypeCode is object, we better have a Contract unless the value itself // was null to begin with. In this case, we just want a RemoteArgument for a // null contract. throw new ArgumentException(null, "value"); } else if ((typeCodeToUse == TypeCode.Empty) && (value != System.Reflection.Missing.Value)) { // If the TypeCode is Empty the only valid value is Missing.Value. throw new ArgumentException(null, "value"); } else if ((convertibleValue == null) && (value != null) && (arrayValue == null) && (typeCodeToUse != TypeCode.Object) && (typeCodeToUse != TypeCode.Empty)) { // All the rest of the TypeCodes are for Convertible values, so we better // have one unless of course the value itself was null (i.e. a null string). // In this case, null is completely valid and we should create a null // string RemoteArgument. throw new ArgumentException(null, "value"); } if (arrayValue != null) { TypeCode arrayTypeCode = Type.GetTypeCode(arrayValue.GetType().GetElementType()); if ((arrayTypeCode == TypeCode.Object) || (arrayTypeCode != typeCodeToUse)) throw new ArgumentException(null, "value"); return new RemoteArgument(arrayValue, isByRef); } bool needsConversion = false; if (convertibleValue != null) needsConversion = (convertibleValue.GetTypeCode() != typeCodeToUse); //all of this seemingly duplicated code //is necessary to unbox the value and call the //correct constructor on RemoteArgument switch (typeCodeToUse) { case TypeCode.Boolean: { bool boolToUse; if (needsConversion) boolToUse = convertibleValue.ToBoolean(null); else boolToUse = (bool)convertibleValue; return new RemoteArgument(boolToUse, isByRef); } case TypeCode.Byte: { byte byteToUse; if (needsConversion) byteToUse = convertibleValue.ToByte(null); else byteToUse = (byte)convertibleValue; return new RemoteArgument(byteToUse, isByRef); } case TypeCode.Char: { char charToUse; if (needsConversion) charToUse = convertibleValue.ToChar(null); else charToUse = (char)convertibleValue; return new RemoteArgument(charToUse, isByRef); } case TypeCode.DateTime: { DateTime dateTimeToUse; if (needsConversion) dateTimeToUse = convertibleValue.ToDateTime(null); else dateTimeToUse = (DateTime)convertibleValue; return new RemoteArgument(dateTimeToUse, isByRef); } case TypeCode.DBNull: { //there is no conversion to DBNull //its either DBNull or not, so //throw if needs conversion is true if (needsConversion) throw new NotSupportedException(); return new RemoteArgument((DBNull)convertibleValue); } case TypeCode.Decimal: { decimal decimalToUse; if (needsConversion) decimalToUse = convertibleValue.ToDecimal(null); else decimalToUse = (decimal)convertibleValue; return new RemoteArgument(decimalToUse, isByRef); } case TypeCode.Double: { double doubleToUse; if (needsConversion) doubleToUse = convertibleValue.ToDouble(null); else doubleToUse = (double)convertibleValue; return new RemoteArgument(doubleToUse, isByRef); } case TypeCode.Int16: { short shortToUse; if (needsConversion) shortToUse = convertibleValue.ToInt16(null); else shortToUse = (short)convertibleValue; return new RemoteArgument(shortToUse, isByRef); } case TypeCode.Int32: { int intToUse; if (needsConversion) intToUse = convertibleValue.ToInt32(null); else intToUse = (int)convertibleValue; return new RemoteArgument(intToUse, isByRef); } case TypeCode.Int64: { long longToUse; if (needsConversion) longToUse = convertibleValue.ToInt64(null); else longToUse = (long)convertibleValue; return new RemoteArgument(longToUse, isByRef); } case TypeCode.SByte: { sbyte sbyteToUse; if (needsConversion) sbyteToUse = convertibleValue.ToSByte(null); else sbyteToUse = (sbyte)convertibleValue; return new RemoteArgument(sbyteToUse, isByRef); } case TypeCode.Single: { float floatToUse; if (needsConversion) floatToUse = convertibleValue.ToSingle(null); else floatToUse = (float)convertibleValue; return new RemoteArgument(floatToUse, isByRef); } case TypeCode.String: { string stringToUse; if (needsConversion) stringToUse = convertibleValue.ToString(null); else stringToUse = (string)convertibleValue; return new RemoteArgument(stringToUse, isByRef); } case TypeCode.UInt16: { ushort ushortToUse; if (needsConversion) ushortToUse = convertibleValue.ToUInt16(null); else ushortToUse = (ushort)convertibleValue; return new RemoteArgument(ushortToUse, isByRef); } case TypeCode.UInt32: { uint uintToUse; if (needsConversion) uintToUse = convertibleValue.ToUInt32(null); else uintToUse = (uint)convertibleValue; return new RemoteArgument(uintToUse, isByRef); } case TypeCode.UInt64: { ulong ulongToUse; if (needsConversion) ulongToUse = convertibleValue.ToUInt64(null); else ulongToUse = (ulong)convertibleValue; return new RemoteArgument(ulongToUse, isByRef); } case TypeCode.Empty: { // Just Missing.Value return new RemoteArgument(RemoteArgumentKind.Missing, TypeCode.Empty, isByRef); } case TypeCode.Object: { return new RemoteArgument(contractValue, isByRef); } default: throw new InvalidOperationException(); } } #endregion #region Initializers //the "default constructor" of RemoteArgument is //built-in because this is a struct. //it creates the "Null" RemoteArgument: //value = null; //remoteArgKing = RemoteArgumentKind.Missing //intrinsicTypeCode = TypeCode.Empty #region Contract //Creates the Contract RemoteArgument public RemoteArgument(IContract value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Contract; this.intrinsicTypeCode = TypeCode.Object; this.isByRef = false; } public RemoteArgument(IContract value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Contract; this.intrinsicTypeCode = TypeCode.Object; this.isByRef = isByRef; } #endregion #region Special case for null/"out" params and/or default value intrinsics //isByRef == true means "out". Must be true if Kind == Contract public RemoteArgument(RemoteArgumentKind remoteArgKind, TypeCode typeCode) : this(remoteArgKind, typeCode, false) { } public RemoteArgument(RemoteArgumentKind remoteArgKind, TypeCode typeCode, bool isByRef) { this._value = null; this.isByRef = isByRef; this.remoteArgKind = remoteArgKind; switch (remoteArgKind) { case RemoteArgumentKind.Missing: if (typeCode != TypeCode.Empty) throw new ArgumentException(null, "typeCode"); this.intrinsicTypeCode = typeCode; break; case RemoteArgumentKind.Intrinsic: case RemoteArgumentKind.IntrinsicArray: if (typeCode == TypeCode.Object || typeCode == TypeCode.Empty) throw new ArgumentException(null, "typeCode"); this.intrinsicTypeCode = typeCode; break; case RemoteArgumentKind.Contract: if (typeCode != TypeCode.Object) throw new ArgumentException(null, "typeCode"); this.intrinsicTypeCode = typeCode; break; default: throw new InvalidOperationException(); } } #endregion #region Primitive Types -- CLS Compliant //two for each of the primitive types //value, by ref #region System.Boolean public RemoteArgument(System.Boolean value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Boolean; this.isByRef = false; } public RemoteArgument(System.Boolean value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Boolean; this.isByRef = isByRef; } #endregion #region System.Byte public RemoteArgument(System.Byte value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Byte; this.isByRef = false; } public RemoteArgument(System.Byte value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Byte; this.isByRef = isByRef; } #endregion #region System.Char public RemoteArgument(System.Char value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Char; this.isByRef = false; } public RemoteArgument(System.Char value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Char; this.isByRef = isByRef; } #endregion #region System.DateTime public RemoteArgument(System.DateTime value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DateTime; this.isByRef = false; } public RemoteArgument(System.DateTime value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DateTime; this.isByRef = isByRef; } #endregion #region System.DBNull public RemoteArgument(System.DBNull value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DBNull; this.isByRef = false; } public RemoteArgument(System.DBNull value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.DBNull; this.isByRef = isByRef; } #endregion #region System.Decimal public RemoteArgument(System.Decimal value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Decimal; this.isByRef = false; } public RemoteArgument(System.Decimal value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Decimal; this.isByRef = isByRef; } #endregion #region System.Double public RemoteArgument(System.Double value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Double; this.isByRef = false; } public RemoteArgument(System.Double value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Double; this.isByRef = isByRef; } #endregion #region System.Int16 public RemoteArgument(System.Int16 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int16; this.isByRef = false; } public RemoteArgument(System.Int16 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int16; this.isByRef = isByRef; } #endregion #region System.Int32 public RemoteArgument(System.Int32 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int32; this.isByRef = false; } public RemoteArgument(System.Int32 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int32; this.isByRef = isByRef; } #endregion #region System.Int64 public RemoteArgument(System.Int64 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int64; this.isByRef = false; } public RemoteArgument(System.Int64 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Int64; this.isByRef = isByRef; } #endregion #region System.Single public RemoteArgument(System.Single value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Single; this.isByRef = false; } public RemoteArgument(System.Single value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.Single; this.isByRef = isByRef; } #endregion #region System.String public RemoteArgument(System.String value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.String; this.isByRef = false; } public RemoteArgument(System.String value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.String; this.isByRef = isByRef; } #endregion #endregion #region Intrinsic Types Non-CLS Compliant #region System.SByte [CLSCompliant(false)] public RemoteArgument(System.SByte value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.SByte; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.SByte value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.SByte; this.isByRef = isByRef; } #endregion #region System.UInt16 [CLSCompliant(false)] public RemoteArgument(System.UInt16 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt16; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.UInt16 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt16; this.isByRef = isByRef; } #endregion #region System.UInt32 [CLSCompliant(false)] public RemoteArgument(System.UInt32 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt32; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.UInt32 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt32; this.isByRef = isByRef; } #endregion #region System.UInt64 [CLSCompliant(false)] public RemoteArgument(System.UInt64 value) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt64; this.isByRef = false; } [CLSCompliant(false)] public RemoteArgument(System.UInt64 value, bool isByRef) { this._value = value; this.remoteArgKind = RemoteArgumentKind.Intrinsic; this.intrinsicTypeCode = TypeCode.UInt64; this.isByRef = isByRef; } #endregion #endregion #region IntrinsicArray //we could have overloads for each of the primitive //type arrays, but arrays can be multidimensional //so we'd need this as a catchall anyway. //So this throws if the array element type isn't intrinsic //NOTE we don't support System.Reflection.Missing[] //makes no sense.... public RemoteArgument(System.Array array) { if (array == null) { throw new ArgumentNullException("array"); } //this handles multi-dimensional intrinsic arrays, too. //Jagged arrays are handled recursively as arrays of arrays //we can't just ask the type if it IsPrimitive because string says "false" if (Type.GetTypeCode(array.GetType().GetElementType()) == TypeCode.Object) { throw new ArgumentException(null, "array"); } this._value = array; this.remoteArgKind = RemoteArgumentKind.IntrinsicArray; //for IntrinsicArray this holds the element type code this.intrinsicTypeCode = Type.GetTypeCode(array.GetType().GetElementType()); this.isByRef = false; } public RemoteArgument(System.Array array, bool isByRef) { if (array == null) { throw new ArgumentNullException("array"); } //this handles multi-dimensional intrinsic arrays, too. //Jagged arrays are handled recursively as arrays of arrays //we can't just ask the type if it IsPrimitive because string says "false" if (Type.GetTypeCode(array.GetType().GetElementType()) == TypeCode.Object) { throw new ArgumentException(null, "array"); } this._value = array; this.remoteArgKind = RemoteArgumentKind.IntrinsicArray; //for IntrinsicArray this holds the element type code this.intrinsicTypeCode = Type.GetTypeCode(array.GetType().GetElementType()); this.isByRef = isByRef; } #endregion #endregion #region Public Accessors public RemoteArgumentKind RemoteArgumentKind { get { return this.remoteArgKind; } } public TypeCode TypeCode { get { return this.intrinsicTypeCode; } } public bool IsByRef { get { return this.isByRef; } set { this.isByRef = value; } } #region Type Specific Value Properties /// /// All of these properties do the same thing: /// On get, validate return and typecode, return if /// appropriate, else throw InvalidOperationException /// On set, isByRef MUST be true, then validate kind /// and typecode and set value if appropriate, else /// throw InvalidOperationException /// #region Contract public IContract ContractValue { get { if (this.remoteArgKind == RemoteArgumentKind.Contract && this.intrinsicTypeCode == TypeCode.Object) { //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (IContract)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Contract && this.intrinsicTypeCode == TypeCode.Object) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Reflection.Missing public System.Reflection.Missing MissingValue { get { if (this.remoteArgKind == RemoteArgumentKind.Missing && this.intrinsicTypeCode == TypeCode.Empty) { //only one possible return value... return System.Reflection.Missing.Value; } throw new InvalidOperationException(); } } #endregion #region Primitive Types -- CLS Compliant ////// A Note on the implementation: We could have used /// a generic helper function to eliminate so much duplicated /// code. We chose not to to avoid misuse of the generic argument /// Explicitly coding all of these leaves nothing to interpretation /// on the use of a function. /// #region System.Boolean public System.Boolean BooleanValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Boolean) { if (this._value == null) return default(System.Boolean); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Boolean)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Boolean) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Byte public System.Byte ByteValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Byte) { if (this._value == null) return default(System.Byte); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Byte)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Byte) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Char public System.Char CharValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Char) { if (this._value == null) return default(System.Char); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Char)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Char) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.DateTime public System.DateTime DateTimeValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DateTime) { if (this._value == null) return default(System.DateTime); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.DateTime)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DateTime) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.DBNull public System.DBNull DBNullValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DBNull) { if (this._value == null) return default(System.DBNull); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.DBNull)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.DBNull) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Decimal public System.Decimal DecimalValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Decimal) { if (this._value == null) return default(System.Decimal); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Decimal)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Decimal) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Double public System.Double DoubleValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Double) { if (this._value == null) return default(System.Double); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Double)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Double) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Int16 public System.Int16 Int16Value { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int16) { if (this._value == null) return default(System.Int16); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Int16)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int16) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Int32 public System.Int32 Int32Value { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int32) { if (this._value == null) return default(System.Int32); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Int32)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int32) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Int64 public System.Int64 Int64Value { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int64) { if (this._value == null) return default(System.Int64); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Int64)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Int64) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.Single public System.Single SingleValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Single) { if (this._value == null) return default(System.Single); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Single)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.Single) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.String public System.String StringValue { get { if (this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.String) { if (this._value == null) return default(System.String); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.String)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.String) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #endregion #region Intrinsic Types -- Non-CLS Compliant #region System.SByte [CLSCompliant(false)] public System.SByte SByteValue { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.SByte) { if (this._value == null) return default(System.SByte); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.SByte)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.SByte) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.UInt16 [CLSCompliant(false)] public System.UInt16 UInt16Value { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt16) { if (this._value == null) return default(System.UInt16); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.UInt16)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt16) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.UInt32 [CLSCompliant(false)] public System.UInt32 UInt32Value { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt32) { if (this._value == null) return default(System.UInt32); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.UInt32)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt32) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #region System.UInt64 [CLSCompliant(false)] public System.UInt64 UInt64Value { get { if(this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt64) { if (this._value == null) return default(System.UInt64); //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.UInt64)this._value; } throw new InvalidOperationException(); } set { if(this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.Intrinsic && this.intrinsicTypeCode == TypeCode.UInt64) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #endregion #region IntrinsicArray [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public System.Array ArrayValue { get { if (this.remoteArgKind == RemoteArgumentKind.IntrinsicArray && this.intrinsicTypeCode != TypeCode.Object) { //do explicit cast here instead of "as" //because we *want* it to throw if it is a //bad cast. It would mean an invalid state //of the struct. return (System.Array)this._value; } throw new InvalidOperationException(); } set { if (this.isByRef == true && this.remoteArgKind == RemoteArgumentKind.IntrinsicArray && this.intrinsicTypeCode != TypeCode.Object) { this._value = value; } else { throw new InvalidOperationException(); } } } #endregion #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ColumnResizeAdorner.cs
- TileBrush.cs
- CodeRemoveEventStatement.cs
- Switch.cs
- RawStylusInputReport.cs
- SqlWebEventProvider.cs
- MasterPage.cs
- ReaderContextStackData.cs
- CookielessData.cs
- WebPartChrome.cs
- TableLayoutRowStyleCollection.cs
- HtmlShimManager.cs
- XmlNavigatorStack.cs
- Tuple.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- Int32RectConverter.cs
- DataGridComponentEditor.cs
- SimpleTextLine.cs
- EnumMember.cs
- BuildResult.cs
- TreeNodeConverter.cs
- WebPartCloseVerb.cs
- HttpServerVarsCollection.cs
- __FastResourceComparer.cs
- BoundPropertyEntry.cs
- CollectionViewProxy.cs
- PrintController.cs
- BufferedGraphicsContext.cs
- SchemaConstraints.cs
- RemotingConfigParser.cs
- CollectionEditorDialog.cs
- Native.cs
- ButtonStandardAdapter.cs
- NonClientArea.cs
- contentDescriptor.cs
- UnsignedPublishLicense.cs
- HtmlPanelAdapter.cs
- DecoderReplacementFallback.cs
- WebPartVerbCollection.cs
- AmbientValueAttribute.cs
- OptimizerPatterns.cs
- BuilderPropertyEntry.cs
- IsolatedStorageFilePermission.cs
- ExceptQueryOperator.cs
- TemplateColumn.cs
- TimelineGroup.cs
- ToolStripItemClickedEventArgs.cs
- RoutingConfiguration.cs
- LogSwitch.cs
- HotSpot.cs
- GridView.cs
- KeyboardNavigation.cs
- TabControlCancelEvent.cs
- UncommonField.cs
- XPathAncestorQuery.cs
- ProfessionalColorTable.cs
- IMembershipProvider.cs
- APCustomTypeDescriptor.cs
- ComplexBindingPropertiesAttribute.cs
- HttpCacheVaryByContentEncodings.cs
- Panel.cs
- BufferedOutputStream.cs
- HttpHandlerAction.cs
- xdrvalidator.cs
- X509AsymmetricSecurityKey.cs
- ContractsBCL.cs
- sqlmetadatafactory.cs
- Sequence.cs
- FormatException.cs
- DynamicResourceExtension.cs
- ConcurrentStack.cs
- PeerTransportElement.cs
- SecurityKeyEntropyMode.cs
- TextTabProperties.cs
- CallbackException.cs
- WebPartChrome.cs
- DataGridViewCellLinkedList.cs
- Int32KeyFrameCollection.cs
- BroadcastEventHelper.cs
- Application.cs
- ObjectIDGenerator.cs
- FloaterBaseParagraph.cs
- ListenerConstants.cs
- Timer.cs
- FontFamilyValueSerializer.cs
- Panel.cs
- MouseEvent.cs
- CodeVariableDeclarationStatement.cs
- MaskedTextProvider.cs
- ContextBase.cs
- SerializeAbsoluteContext.cs
- ForceCopyBuildProvider.cs
- ListViewItemEventArgs.cs
- DataSetUtil.cs
- ProtectedConfigurationProviderCollection.cs
- Environment.cs
- TemporaryBitmapFile.cs
- UpDownEvent.cs
- SecurityTokenProvider.cs
- ExpressionEvaluator.cs