// // Copyright (c) ZeroC, Inc. All rights reserved. // namespace Ice { using System; using System.Collections.Generic; using System.Runtime.Serialization; public struct NoneType { } /// /// Encapsulates an optional value. Instances of this type are immutable. /// [Serializable] public struct Optional : ISerializable { /// /// Creates an optional value whose state is unset. /// public Optional(NoneType none) { _value = default(T); _isSet = false; } /// /// Creates an optional value and sets its value to the given argument. /// public Optional(T v) { _value = v; _isSet = true; } /// /// Creates an optional value whose state is copied from the given argument. /// public Optional(Optional v) { _value = v._value; _isSet = v._isSet; } /// /// Initializes a new instance of the exception with serialized data. /// /// Holds the serialized object data about the exception being thrown. /// Contains contextual information about the source or destination. public Optional(SerializationInfo info, StreamingContext context) { _isSet = info.GetBoolean("isSet"); if(_isSet) { _value = (T)info.GetValue("value", typeof(T)); } else { _value = default(T); } } /// /// Conversion operator to the underlying type; a cast is required. An exception /// is raised if no value is set. /// /// The encapsulated value. /// Thrown if no value is set. public static explicit operator T(Optional v) { return v.Value; } /// /// Conversion operator from a value of the underlying type; no cast is required. /// public static implicit operator Optional(T v) { return new Optional(v); } /// /// Conversion operator from a None value; no cast is required. /// public static implicit operator Optional(NoneType v) { return new Optional(); } /// /// Reads and writes the encapsulated value. /// /// Thrown if the property is read and no value is /// set. public T Value { get { if(!_isSet) { throw new InvalidOperationException(); } return _value; } } /// /// Determines whether a value is set. /// /// True if a value is set, false otherwise. public bool HasValue { get { return _isSet; } } public override bool Equals(object other) { if(ReferenceEquals(this, other)) { return true; } if(other == null) { return false; } try { Optional o2 = (Optional)other; if(_isSet != o2._isSet) { return false; } else if(_isSet) { EqualityComparer comparer = EqualityComparer.Default; return comparer.Equals(_value, o2._value); } return true; } catch(System.Exception) { return false; } } public override int GetHashCode() { if(!_isSet) { return base.GetHashCode(); } else { return _value.GetHashCode(); } } /// /// Serializes an optional value. /// /// Holds the serialized object data about the exception being thrown. /// Contains contextual information about the source or destination. public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("isSet", _isSet); if(_isSet) { info.AddValue("value", _value, typeof(T)); } } private T _value; private bool _isSet; } /// /// The optional format. /// /// An optional value is encoded with a specific optional format. This optional /// format describes how the data is encoded and how it can be skipped by the /// unmarshaling code if the optional is not known to the receiver. /// public enum OptionalFormat { F1 = 0, F2 = 1, F4 = 2, F8 = 3, Size = 4, VSize = 5, FSize = 6, Class = 7 } }