Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
LanguagePrimitives.cs5889 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Generic;6using System.Collections.Specialized;7using System.ComponentModel;8using System.Data;9using System.Diagnostics.CodeAnalysis;10using System.Globalization;11using System.IO;12using System.Linq.Expressions;13using System.Management.Automation.Internal;14using System.Management.Automation.Language;15using System.Management.Automation.Runspaces;16using System.Management.Automation.Security;17using System.Numerics;18using System.Reflection;19using System.Reflection.Emit;20using System.Runtime.CompilerServices;21using System.Text;22using System.Text.RegularExpressions;23using System.Xml;24using System.Security;25 26using Dbg = System.Management.Automation.Diagnostics;27using MethodCacheEntry = System.Management.Automation.DotNetAdapter.MethodCacheEntry;28#if !UNIX29using System.DirectoryServices;30#endif31 32#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings33#pragma warning disable 5650034 35namespace System.Management.Automation36{37    #region public type converters38    /// <summary>39    /// Defines a base class implemented when you need to customize the type conversion for a target class.40    /// </summary>41    /// <remarks>42    /// There are two ways of associating the PSTypeConverter with its target class:43    ///     - Through the type configuration file.44    ///     - By applying a TypeConverterAttribute to the target class.45    ///46    /// Unlike System.ComponentModel.TypeConverter, PSTypeConverter can be applied to a family of types (like all types derived from System.Enum).47    /// PSTypeConverter has two main differences from TypeConverter:48    ///     - It can be applied to a family of types and not only the one type as in TypeConverter. In order to do that49    /// ConvertFrom and CanConvertFrom receive destinationType to know to which type specifically we are converting sourceValue.50    ///     - ConvertTo and ConvertFrom receive formatProvider and ignoreCase.51    /// Other differences to System.ComponentModel.TypeConverter:52    ///     - There is no ITypeDescriptorContext.53    ///     - This class is abstract54    /// </remarks>55    public abstract class PSTypeConverter56    {57        private static object GetSourceValueAsObject(PSObject sourceValue)58        {59            if (sourceValue == null)60            {61                return null;62            }63 64            if (sourceValue.BaseObject is PSCustomObject)65            {66                return sourceValue;67            }68            else69            {70                return PSObject.Base(sourceValue);71            }72        }73 74        /// <summary>75        /// Determines if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter.76        /// </summary>77        /// <param name="sourceValue">Value supposedly *not* of the types supported by this converted to be converted to the <paramref name="destinationType"/> parameter.</param>78        /// <param name="destinationType">One of the types supported by this converter to which the <paramref name="sourceValue"/> parameter should be converted.</param>79        /// <returns>True if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter, otherwise false.</returns>80        public abstract bool CanConvertFrom(object sourceValue, Type destinationType);81 82        /// <summary>83        /// Determines if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter.84        /// </summary>85        /// <param name="sourceValue">Value supposedly *not* of the types supported by this converted to be converted to the <paramref name="destinationType"/> parameter.</param>86        /// <param name="destinationType">One of the types supported by this converter to which the <paramref name="sourceValue"/> parameter should be converted.</param>87        /// <returns>True if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter, otherwise false.</returns>88        public virtual bool CanConvertFrom(PSObject sourceValue, Type destinationType)89        {90            return this.CanConvertFrom(GetSourceValueAsObject(sourceValue), destinationType);91        }92 93        /// <summary>94        /// Converts the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.95        /// </summary>96        /// <param name="sourceValue">Value supposedly *not* of the types supported by this converted to be converted to the <paramref name="destinationType"/> parameter.</param>97        /// <param name="destinationType">One of the types supported by this converter to which the <paramref name="sourceValue"/> parameter should be converted to.</param>98        /// <param name="formatProvider">The format provider to use like in IFormattable's ToString.</param>99        /// <param name="ignoreCase">True if case should be ignored.</param>100        /// <returns>The <paramref name="sourceValue"/> parameter converted to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.</returns>101        /// <exception cref="InvalidCastException">If no conversion was possible.</exception>102        public abstract object ConvertFrom(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase);103 104        /// <summary>105        /// Converts the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.106        /// </summary>107        /// <param name="sourceValue">Value supposedly *not* of the types supported by this converted to be converted to the <paramref name="destinationType"/> parameter.</param>108        /// <param name="destinationType">One of the types supported by this converter to which the <paramref name="sourceValue"/> parameter should be converted to.</param>109        /// <param name="formatProvider">The format provider to use like in IFormattable's ToString.</param>110        /// <param name="ignoreCase">True if case should be ignored.</param>111        /// <returns>The <paramref name="sourceValue"/> parameter converted to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.</returns>112        /// <exception cref="InvalidCastException">If no conversion was possible.</exception>113        public virtual object ConvertFrom(PSObject sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)114        {115            return this.ConvertFrom(GetSourceValueAsObject(sourceValue), destinationType, formatProvider, ignoreCase);116        }117 118        /// <summary>119        /// Returns true if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter.120        /// </summary>121        /// <param name="sourceValue">Value supposedly from one of the types supported by this converter to be converted to the <paramref name="destinationType"/> parameter.</param>122        /// <param name="destinationType">Type to convert the <paramref name="sourceValue"/> parameter, supposedly not one of the types supported by the converter.</param>123        /// <returns>True if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter, otherwise false.</returns>124        public abstract bool CanConvertTo(object sourceValue, Type destinationType);125 126        /// <summary>127        /// Returns true if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter.128        /// </summary>129        /// <param name="sourceValue">Value supposedly from one of the types supported by this converter to be converted to the <paramref name="destinationType"/> parameter.</param>130        /// <param name="destinationType">Type to convert the <paramref name="sourceValue"/> parameter, supposedly not one of the types supported by the converter.</param>131        /// <returns>True if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter, otherwise false.</returns>132        public virtual bool CanConvertTo(PSObject sourceValue, Type destinationType)133        {134            return this.CanConvertTo(GetSourceValueAsObject(sourceValue), destinationType);135        }136 137        /// <summary>138        /// Converts the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.139        /// </summary>140        /// <param name="sourceValue">Value supposedly from one of the types supported by this converter to be converted to the <paramref name="destinationType"/> parameter.</param>141        /// <param name="destinationType">Type to convert the <paramref name="sourceValue"/> parameter, supposedly not one of the types supported by the converter.</param>142        /// <param name="formatProvider">The format provider to use like in IFormattable's ToString.</param>143        /// <param name="ignoreCase">True if case should be ignored.</param>144        /// <returns>SourceValue converted to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.</returns>145        /// <exception cref="InvalidCastException">If no conversion was possible.</exception>146        public abstract object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase);147 148        /// <summary>149        /// Converts the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.150        /// </summary>151        /// <param name="sourceValue">Value supposedly from one of the types supported by this converter to be converted to the <paramref name="destinationType"/> parameter.</param>152        /// <param name="destinationType">Type to convert the <paramref name="sourceValue"/> parameter, supposedly not one of the types supported by the converter.</param>153        /// <param name="formatProvider">The format provider to use like in IFormattable's ToString.</param>154        /// <param name="ignoreCase">True if case should be ignored.</param>155        /// <returns>SourceValue converted to the <paramref name="destinationType"/> parameter using formatProvider and ignoreCase.</returns>156        /// <exception cref="InvalidCastException">If no conversion was possible.</exception>157        public virtual object ConvertTo(PSObject sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)158        {159            return this.ConvertTo(GetSourceValueAsObject(sourceValue), destinationType, formatProvider, ignoreCase);160        }161    }162 163    /// <summary>164    /// Enables a type that only has conversion from string to be converted from all other165    /// types through string.166    /// </summary>167    /// <remarks>168    /// It is permitted to subclass <see cref="ConvertThroughString"/>169    /// but there is no established scenario for doing this, nor has it been tested.170    /// </remarks>171    public class ConvertThroughString : PSTypeConverter172    {173        /// <summary>174        /// This will return false only if sourceValue is string.175        /// </summary>176        /// <param name="sourceValue">Value to convert from.</param>177        /// <param name="destinationType">Ignored.</param>178        /// <returns>False only if sourceValue is string.</returns>179        public override bool CanConvertFrom(object sourceValue, Type destinationType)180        {181            // This if avoids infinite recursion.182            if (sourceValue is string)183            {184                return false;185            }186 187            return true;188        }189 190        /// <summary>191        /// Converts to destinationType by first converting sourceValue to string192        /// and then converting the result to destinationType.193        /// </summary>194        /// <param name="sourceValue">The value to convert from.</param>195        /// <param name="destinationType">The type this converter is associated with.</param>196        /// <param name="formatProvider">The IFormatProvider to use.</param>197        /// <param name="ignoreCase">True if case should be ignored.</param>198        /// <returns>SourceValue converted to destinationType.</returns>199        /// <exception cref="PSInvalidCastException">When no conversion was possible.</exception>200        public override object ConvertFrom(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)201        {202            string sourceAsString = (string)LanguagePrimitives.ConvertTo(sourceValue, typeof(string), formatProvider);203            return LanguagePrimitives.ConvertTo(sourceAsString, destinationType, formatProvider);204        }205        /// <summary>206        /// Returns false, since this converter is not designed to be used to207        /// convert from the type associated with the converted to other types.208        /// </summary>209        /// <param name="sourceValue">The value to convert from.</param>210        /// <param name="destinationType">The value to convert from.</param>211        /// <returns>False.</returns>212        public override bool CanConvertTo(object sourceValue, Type destinationType)213        {214            return false;215        }216 217        /// <summary>218        /// Throws NotSupportedException, since this converter is not designed to be used to219        /// convert from the type associated with the converted to other types.220        /// </summary>221        /// <param name="sourceValue">The value to convert from.</param>222        /// <param name="destinationType">The value to convert from.</param>223        /// <param name="formatProvider">The IFormatProvider to use.</param>224        /// <param name="ignoreCase">True if case should be ignored.</param>225        /// <returns>This method does not return a value.</returns>226        /// <exception cref="NotSupportedException">NotSupportedException is always thrown.</exception>227        public override object ConvertTo(object sourceValue, Type destinationType, IFormatProvider formatProvider, bool ignoreCase)228        {229            throw PSTraceSource.NewNotSupportedException();230        }231    }232    #endregion public type converters233 234    /// <summary>235    /// The ranking of versions for comparison purposes (used in overload resolution.)236    /// A larger value means the conversion is better.237    ///238    /// Note that the lower nibble is all ones for named conversion ranks.  This allows for239    /// conversions with rankings in between the named values.  For example, int=>string[]240    /// is value dependent, if the conversion from int=>string succeeds, then an array is241    /// created, otherwise we try some other conversion.  The int=>string[] conversion should242    /// be worse than int=>string, but it is probably better than many other conversions, so243    /// we want it to be only slightly worse than int=>string.244    /// </summary>245    /// <remarks>246    /// ValueDependent is a flag, but we don't mark the enum as flags because it really isn't247    /// a flags enum.248    /// To make debugging easier, the "in between" conversions are all named, though there are249    /// no references in the code.  They all use the suffix S2A which means "scalar to array".250    /// </remarks>251    internal enum ConversionRank252    {253        None = 0x0000,254        UnrelatedArraysS2A = 0x0007,255        UnrelatedArrays = 0x000F,256        ToStringS2A = 0x0017,257        ToString = 0x001F,258        CustomS2A = 0x0027,259        Custom = 0x002F,260        IConvertibleS2A = 0x0037,261        IConvertible = 0x003F,262        ImplicitCastS2A = 0x0047,263        ImplicitCast = 0x004F,264        ExplicitCastS2A = 0x0057,265        ExplicitCast = 0x005F,266        ConstructorS2A = 0x0067,267        Constructor = 0x006F,268        Create = 0x0073,269        ParseS2A = 0x0077,270        Parse = 0x007F,271        PSObjectS2A = 0x0087,272        PSObject = 0x008F,273        LanguageS2A = 0x0097,274        Language = 0x009F,275        NullToValue = 0x00AF,276        NullToRef = 0x00BF,277        NumericExplicitS2A = 0x00C7,278        NumericExplicit = 0x00CF,279        NumericExplicit1S2A = 0x00D7,280        NumericExplicit1 = 0x00DF,281        NumericStringS2A = 0x00E7,282        NumericString = 0x00EF,283        NumericImplicitS2A = 0x00F7,284        NumericImplicit = 0x00FF,285        AssignableS2A = 0x0107,286        Assignable = 0x010F,287        IdentityS2A = 0x0117,288        StringToCharArray = 0x011A,289        Identity = 0x011F,290 291        ValueDependent = 0xFFF7,292    }293 294    /// <summary>295    /// Defines language support methods.296    /// </summary>297    [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Refactoring LanguagePrimitives takes lot of dev/test effort. Since V1 code is already shipped, we tend to exclude this message.")]298    public static class LanguagePrimitives299    {300        [TraceSource("ETS", "Extended Type System")]301        private static readonly PSTraceSource s_tracer = PSTraceSource.GetTracer("ETS", "Extended Type System");302 303        internal delegate void MemberNotFoundError(PSObject pso, DictionaryEntry property, Type resultType);304 305        internal delegate void MemberSetValueError(SetValueException e);306 307        internal const string OrderedAttribute = "ordered";308        internal const string DoublePrecision = "G15";309        internal const string SinglePrecision = "G7";310 311        internal static void CreateMemberNotFoundError(PSObject pso, DictionaryEntry property, Type resultType)312        {313            string settableProperties = GetSettableProperties(pso);314 315            string message = settableProperties == string.Empty316                ? StringUtil.Format(ExtendedTypeSystem.NoSettableProperty, property.Key.ToString(), resultType.FullName)317                : StringUtil.Format(ExtendedTypeSystem.PropertyNotFound, property.Key.ToString(), resultType.FullName, settableProperties);318 319            typeConversion.WriteLine("Issuing an error message about not being able to create an object from hashtable.");320            throw new InvalidOperationException(message);321        }322 323        internal static void CreateMemberSetValueError(SetValueException e)324        {325            typeConversion.WriteLine("Issuing an error message about not being able to set the properties for an object.");326            throw e;327        }328 329        static LanguagePrimitives()330        {331            RebuildConversionCache();332            InitializeGetEnumerableCache();333 334#if !CORECLR // AppDomain Not In CoreCLR335            AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveHelper;336#endif337        }338 339        internal static void UpdateTypeConvertFromTypeTable(string typeName)340        {341            lock (s_converterCache)342            {343                foreach (var key in s_converterCache.Keys)344                {345                    if (string.Equals(key.to.FullName, typeName, StringComparison.OrdinalIgnoreCase)346                        || string.Equals(key.from.FullName, typeName, StringComparison.OrdinalIgnoreCase))347                    {348                        s_converterCache.Remove(key);349                    }350                }351 352                // Note we do not clear possibleTypeConverter even when removing.353                //354                // The conversion cache and the possibleTypeConverter cache are process wide, but355                // the type table used for any specific conversion is runspace specific.356                s_possibleTypeConverter[typeName] = true;357            }358        }359 360        #region GetEnumerable/GetEnumerator361 362        /// <summary>363        /// This is a wrapper class that allows us to use the generic IEnumerable364        /// implementation of an object when we can't use it's non-generic365        /// implementation.366        /// </summary>367        private sealed class EnumerableTWrapper : IEnumerable368        {369            private readonly object _enumerable;370            private readonly Type _enumerableType;371            private DynamicMethod _getEnumerator;372 373            internal EnumerableTWrapper(object enumerable, Type enumerableType)374            {375                _enumerable = enumerable;376                _enumerableType = enumerableType;377                CreateGetEnumerator();378            }379 380            private void CreateGetEnumerator()381            {382                _getEnumerator = new DynamicMethod("GetEnumerator", typeof(object),383                    new Type[] { typeof(object) }, typeof(LanguagePrimitives).Module, true);384 385                ILGenerator emitter = _getEnumerator.GetILGenerator();386 387                emitter.Emit(OpCodes.Ldarg_0);388                emitter.Emit(OpCodes.Castclass, _enumerableType);389                MethodInfo methodInfo = _enumerableType.GetMethod("GetEnumerator", Array.Empty<Type>());390                emitter.Emit(OpCodes.Callvirt, methodInfo);391                emitter.Emit(OpCodes.Ret);392            }393 394            #region IEnumerable Members395 396            public IEnumerator GetEnumerator()397            {398                return (IEnumerator)_getEnumerator.Invoke(null, new object[] { _enumerable });399            }400 401            #endregion402        }403 404        private static IEnumerable GetEnumerableFromIEnumerableT(object obj)405        {406            foreach (Type i in obj.GetType().GetInterfaces())407            {408                if (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))409                {410                    return new EnumerableTWrapper(obj, i);411                }412            }413 414            return null;415        }416 417        private delegate IEnumerable GetEnumerableDelegate(object obj);418 419        private static readonly Dictionary<Type, GetEnumerableDelegate> s_getEnumerableCache = new Dictionary<Type, GetEnumerableDelegate>(32);420 421        private static GetEnumerableDelegate GetOrCalculateEnumerable(Type type)422        {423            GetEnumerableDelegate getEnumerable = null;424            lock (s_getEnumerableCache)425            {426                if (!s_getEnumerableCache.TryGetValue(type, out getEnumerable))427                {428                    getEnumerable = CalculateGetEnumerable(type);429                    s_getEnumerableCache.Add(type, getEnumerable);430                }431            }432 433            return getEnumerable;434        }435 436        private static void InitializeGetEnumerableCache()437        {438            lock (s_getEnumerableCache)439            {440                // PowerShell doesn't treat strings as enumerables so just return null.441                // we also want to return null on common numeric types very quickly442                s_getEnumerableCache.Clear();443                s_getEnumerableCache.Add(typeof(string), LanguagePrimitives.ReturnNullEnumerable);444                s_getEnumerableCache.Add(typeof(int), LanguagePrimitives.ReturnNullEnumerable);445                s_getEnumerableCache.Add(typeof(double), LanguagePrimitives.ReturnNullEnumerable);446            }447        }448 449        internal static bool IsTypeEnumerable(Type type)450        {451            if (type == null) { return false; }452 453            GetEnumerableDelegate getEnumerable = GetOrCalculateEnumerable(type);454            return (getEnumerable != LanguagePrimitives.ReturnNullEnumerable);455        }456 457        /// <summary>458        /// Returns True if the language considers obj to be IEnumerable.459        /// </summary>460        /// <param name="obj">461        /// IEnumerable or IEnumerable-like object462        /// </param>463        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "Since V1 code is already shipped, excluding this message.")]464        public static bool IsObjectEnumerable(object obj)465        {466            return IsTypeEnumerable(PSObject.Base(obj)?.GetType());467        }468 469        /// <summary>470        /// Retrieves the IEnumerable of obj or null if the language does not consider obj to be IEnumerable.471        /// </summary>472        /// <param name="obj">473        /// IEnumerable or IEnumerable-like object474        /// </param>475        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "Since V1 code is already shipped, excluding this message.")]476        public static IEnumerable GetEnumerable(object obj)477        {478            obj = PSObject.Base(obj);479            if (obj == null) { return null; }480 481            GetEnumerableDelegate getEnumerable = GetOrCalculateEnumerable(obj.GetType());482            return getEnumerable(obj);483        }484 485        private static IEnumerable ReturnNullEnumerable(object obj)486        {487            return null;488        }489 490        private static IEnumerable DataTableEnumerable(object obj)491        {492            return (((DataTable)obj).Rows);493        }494 495        private static IEnumerable TypicalEnumerable(object obj)496        {497            IEnumerable e = (IEnumerable)obj;498            try499            {500                // Some IEnumerable implementations just return null.  Others501                // raise an exception.  Either of these may have a perfectly502                // good generic implementation, so we'll try those if the503                // non-generic is no good.504                if (e.GetEnumerator() == null)505                {506                    return GetEnumerableFromIEnumerableT(obj);507                }508 509                return e;510            }511            catch (Exception innerException)512            {513                e = GetEnumerableFromIEnumerableT(obj);514                if (e != null)515                {516                    return e;517                }518 519                throw new ExtendedTypeSystemException(520                    "ExceptionInGetEnumerator",521                    innerException,522                    ExtendedTypeSystem.EnumerationException,523                    innerException.Message);524            }525        }526 527        private static GetEnumerableDelegate CalculateGetEnumerable(Type objectType)528        {529            if (typeof(DataTable).IsAssignableFrom(objectType))530            {531                return LanguagePrimitives.DataTableEnumerable;532            }533 534            // Don't treat IDictionary or XmlNode as enumerable...535            if (typeof(IEnumerable).IsAssignableFrom(objectType)536                && !typeof(IDictionary).IsAssignableFrom(objectType)537                && !typeof(XmlNode).IsAssignableFrom(objectType))538            {539                return LanguagePrimitives.TypicalEnumerable;540            }541 542            return LanguagePrimitives.ReturnNullEnumerable;543        }544 545        private static readonly CallSite<Func<CallSite, object, IEnumerator>> s_getEnumeratorSite =546            CallSite<Func<CallSite, object, IEnumerator>>.Create(PSEnumerableBinder.Get());547 548        /// <summary>549        /// Retrieves the IEnumerator of obj or null if the language does not consider obj as capable of returning an IEnumerator.550        /// </summary>551        /// <param name="obj">552        /// IEnumerable or IEnumerable-like object553        /// </param>554        /// <exception cref="ExtendedTypeSystemException">When the act of getting the enumerator throws an exception.</exception>555        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "Since V1 code is already shipped, excluding this message for backward compatibility reasons.")]556        public static IEnumerator GetEnumerator(object obj)557        {558            var result = s_getEnumeratorSite.Target.Invoke(s_getEnumeratorSite, obj);559            return (result is EnumerableOps.NonEnumerableObjectEnumerator) ? null : result;560        }561 562        #endregion GetEnumerable/GetEnumerator563 564        /// <summary>565        /// This method takes a an arbitrary object and wraps it in a PSDataCollection of PSObject.566        /// This simplifies interacting with the PowerShell workflow activities.567        /// </summary>568        /// <param name="inputValue"></param>569        /// <returns></returns>570        public static PSDataCollection<PSObject> GetPSDataCollection(object inputValue)571        {572            PSDataCollection<PSObject> result = new PSDataCollection<PSObject>();573            if (inputValue != null)574            {575                IEnumerator e = GetEnumerator(inputValue);576                if (e != null)577                {578                    while (e.MoveNext())579                    {580                        result.Add(e.Current == null ? null : PSObject.AsPSObject(e.Current));581                    }582                }583                else584                {585                    result.Add(PSObject.AsPSObject(inputValue));586                }587            }588 589            result.Complete();590            return result;591        }592 593        /// <summary>594        /// Used to compare two objects for equality converting the second to the type of the first, if required.595        /// </summary>596        /// <param name="first">First object.</param>597        /// <param name="second">Object to compare first to.</param>598        /// <returns>True if first is equal to the second.</returns>599        public static new bool Equals(object first, object second)600        {601            return Equals(first, second, false, CultureInfo.InvariantCulture);602        }603 604        /// <summary>605        /// Used to compare two objects for equality converting the second to the type of the first, if required.606        /// </summary>607        /// <param name="first">First object.</param>608        /// <param name="second">Object to compare first to.</param>609        /// <param name="ignoreCase">used only if first and second are strings610        /// to specify the type of string comparison </param>611        /// <returns>True if first is equal to the second.</returns>612        public static bool Equals(object first, object second, bool ignoreCase)613        {614            return Equals(first, second, ignoreCase, CultureInfo.InvariantCulture);615        }616 617        /// <summary>618        /// Used to compare two objects for equality converting the second to the type of the first, if required.619        /// </summary>620        /// <param name="first">First object.</param>621        /// <param name="second">Object to compare first to.</param>622        /// <param name="ignoreCase">used only if first and second are strings623        /// to specify the type of string comparison </param>624        /// <param name="formatProvider">the format/culture to be used. If this parameter is null,625        /// CultureInfo.InvariantCulture will be used.626        /// </param>627        /// <returns>True if first is equal to the second.</returns>628        public static bool Equals(object first, object second, bool ignoreCase, IFormatProvider formatProvider)629        {630            // If both first and second are null it returns true.631            // If one is null and the other is not it returns false.632            // if (first.Equals(second)) it returns true otherwise it goes ahead with type conversion operations.633            // If both first and second are strings it returns (string.Compare(firstString, secondString, ignoreCase) == 0).634            // If second can be converted to the type of the first, it does so and returns first.Equals(secondConverted)635            // Otherwise false is returned636 637            formatProvider ??= CultureInfo.InvariantCulture;638 639            if (formatProvider is not CultureInfo culture)640            {641                throw PSTraceSource.NewArgumentException(nameof(formatProvider));642            }643 644            first = PSObject.Base(first);645            second = PSObject.Base(second);646 647            if (first == null)648            {649                return second == null;650            }651 652            if (second == null)653            {654                return false; // first is not null655            }656 657            string firstString = first as string;658            string secondString;659            if (firstString != null)660            {661                secondString = second as string ?? (string)LanguagePrimitives.ConvertTo(second, typeof(string), culture);662                return (culture.CompareInfo.Compare(firstString, secondString,663                                                    ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0);664            }665 666            if (first.Equals(second)) return true;667 668            Type firstType = first.GetType();669            Type secondType = second.GetType();670            int firstIndex = LanguagePrimitives.TypeTableIndex(firstType);671            int secondIndex = LanguagePrimitives.TypeTableIndex(secondType);672            if ((firstIndex != -1) && (secondIndex != -1))673            {674                return LanguagePrimitives.NumericCompare(first, second, firstIndex, secondIndex) == 0;675            }676 677            if (firstType == typeof(char) && ignoreCase)678            {679                secondString = second as string;680                if (secondString != null && secondString.Length == 1)681                {682                    char firstAsUpper = culture.TextInfo.ToUpper((char)first);683                    char secondAsUpper = culture.TextInfo.ToUpper(secondString[0]);684                    return firstAsUpper.Equals(secondAsUpper);685                }686                else if (secondType == typeof(char))687                {688                    char firstAsUpper = culture.TextInfo.ToUpper((char)first);689                    char secondAsUpper = culture.TextInfo.ToUpper((char)second);690                    return firstAsUpper.Equals(secondAsUpper);691                }692            }693 694            try695            {696                object secondConverted = LanguagePrimitives.ConvertTo(second, firstType, culture);697                return first.Equals(secondConverted);698            }699            catch (InvalidCastException)700            {701            }702 703            return false;704        }705 706        /// <summary>707        /// Helper method for [Try]Compare to determine object ordering with null.708        /// </summary>709        /// <param name="value">The numeric value to compare to null.</param>710        /// <param name="numberIsRightHandSide">True if the number to compare is on the right hand side if the comparison.</param>711        private static int CompareObjectToNull(object value, bool numberIsRightHandSide)712        {713            var i = numberIsRightHandSide ? -1 : 1;714 715            // If it's a positive number, including 0, it's greater than null716            // for everything else it's less than zero...717            switch (value)718            {719                case Int16 i16: return Math.Sign(i16) < 0 ? -i : i;720                case Int32 i32: return Math.Sign(i32) < 0 ? -i : i;721                case Int64 i64: return Math.Sign(i64) < 0 ? -i : i;722                case sbyte sby: return Math.Sign(sby) < 0 ? -i : i;723                case float f: return Math.Sign(f) < 0 ? -i : i;724                case double d: return Math.Sign(d) < 0 ? -i : i;725                case decimal de: return Math.Sign(de) < 0 ? -i : i;726                default: return i;727            }728        }729 730        /// <summary>731        /// Compare first and second, converting second to the732        /// type of the first, if necessary.733        /// </summary>734        /// <param name="first">First comparison value.</param>735        /// <param name="second">Second comparison value.</param>736        /// <returns>Less than zero if first is smaller than second, more than737        /// zero if it is greater or zero if they are the same.</returns>738        /// <exception cref="System.ArgumentException">739        /// <paramref name="first"/> does not implement IComparable or <paramref name="second"/> cannot be converted740        /// to the type of <paramref name="first"/>.741        /// </exception>742        public static int Compare(object first, object second)743        {744            return LanguagePrimitives.Compare(first, second, false, CultureInfo.InvariantCulture);745        }746 747        /// <summary>748        /// Compare first and second, converting second to the749        /// type of the first, if necessary.750        /// </summary>751        /// <param name="first">First comparison value.</param>752        /// <param name="second">Second comparison value.</param>753        /// <param name="ignoreCase">Used if both values are strings.</param>754        /// <returns>Less than zero if first is smaller than second, more than755        /// zero if it is greater or zero if they are the same.</returns>756        /// <exception cref="System.ArgumentException">757        /// <paramref name="first"/> does not implement IComparable or <paramref name="second"/> cannot be converted758        /// to the type of <paramref name="first"/>.759        /// </exception>760        public static int Compare(object first, object second, bool ignoreCase)761        {762            return LanguagePrimitives.Compare(first, second, ignoreCase, CultureInfo.InvariantCulture);763        }764 765        /// <summary>766        /// Compare first and second, converting second to the767        /// type of the first, if necessary.768        /// </summary>769        /// <param name="first">First comparison value.</param>770        /// <param name="second">Second comparison value.</param>771        /// <param name="ignoreCase">Used if both values are strings.</param>772        /// <param name="formatProvider">Used in type conversions and if both values are strings.</param>773        /// <returns>Less than zero if first is smaller than second, more than774        /// zero if it is greater or zero if they are the same.</returns>775        /// <exception cref="System.ArgumentException">776        /// <paramref name="first"/> does not implement IComparable or <paramref name="second"/> cannot be converted777        /// to the type of <paramref name="first"/>.778        /// </exception>779        public static int Compare(object first, object second, bool ignoreCase, IFormatProvider formatProvider)780        {781            formatProvider ??= CultureInfo.InvariantCulture;782 783            if (formatProvider is not CultureInfo culture)784            {785                throw PSTraceSource.NewArgumentException(nameof(formatProvider));786            }787 788            first = PSObject.Base(first);789            second = PSObject.Base(second);790 791            if (first == null)792            {793                return second == null ? 0 : CompareObjectToNull(second, true);794            }795 796            if (second == null)797            {798                return CompareObjectToNull(first, false);799            }800 801            if (first is string firstString)802            {803                string secondString = second as string;804                if (secondString == null)805                {806                    try807                    {808                        secondString = (string)LanguagePrimitives.ConvertTo(second, typeof(string), culture);809                    }810                    catch (PSInvalidCastException e)811                    {812                        throw PSTraceSource.NewArgumentException(nameof(second), ExtendedTypeSystem.ComparisonFailure,813                                                                 first.ToString(), second.ToString(), e.Message);814                    }815                }816 817                return culture.CompareInfo.Compare(firstString, secondString,818                                                   ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);819            }820 821            Type firstType = first.GetType();822            Type secondType = second.GetType();823            int firstIndex = LanguagePrimitives.TypeTableIndex(firstType);824            int secondIndex = LanguagePrimitives.TypeTableIndex(secondType);825            if ((firstIndex != -1) && (secondIndex != -1))826            {827                return LanguagePrimitives.NumericCompare(first, second, firstIndex, secondIndex);828            }829 830            object secondConverted;831            try832            {833                secondConverted = LanguagePrimitives.ConvertTo(second, firstType, culture);834            }835            catch (PSInvalidCastException e)836            {837                throw PSTraceSource.NewArgumentException(nameof(second), ExtendedTypeSystem.ComparisonFailure,838                                                         first.ToString(), second.ToString(), e.Message);839            }840 841            if (first is IComparable firstComparable)842            {843                return firstComparable.CompareTo(secondConverted);844            }845 846            if (first.Equals(second))847            {848                return 0;849            }850 851            // At this point, we know that they aren't equal but we have no way of852            // knowing which should compare greater than the other so we throw an exception.853            throw PSTraceSource.NewArgumentException(nameof(first), ExtendedTypeSystem.NotIcomparable, first.ToString());854        }855 856        /// <summary>857        /// Tries to compare first and second, converting second to the type of the first, if necessary.858        /// If a conversion is needed but fails, false is return.859        /// </summary>860        /// <param name="first">First comparison value.</param>861        /// <param name="second">Second comparison value.</param>862        /// <param name="result">Less than zero if first is smaller than second, more than863        /// zero if it is greater or zero if they are the same.</param>864        /// <returns>True if the comparison was successful, false otherwise.</returns>865        public static bool TryCompare(object first, object second, out int result)866        {867            return TryCompare(first, second, ignoreCase: false, CultureInfo.InvariantCulture, out result);868        }869 870        /// <summary>871        /// Tries to compare first and second, converting second to the type of the first, if necessary.872        /// If a conversion is needed but fails, false is return.873        /// </summary>874        /// <param name="first">First comparison value.</param>875        /// <param name="second">Second comparison value.</param>876        /// <param name="ignoreCase">Used if both values are strings.</param>877        /// <param name="result">Less than zero if first is smaller than second, more than zero if it is greater or zero if they are the same.</param>878        /// <returns>True if the comparison was successful, false otherwise.</returns>879        public static bool TryCompare(object first, object second, bool ignoreCase, out int result)880        {881            return TryCompare(first, second, ignoreCase, CultureInfo.InvariantCulture, out result);882        }883 884        /// <summary>885        /// Tries to compare first and second, converting second to the type of the first, if necessary.886        /// If a conversion is needed but fails, false is return.887        /// </summary>888        /// <param name="first">First comparison value.</param>889        /// <param name="second">Second comparison value.</param>890        /// <param name="ignoreCase">Used if both values are strings.</param>891        /// <param name="formatProvider">Used in type conversions and if both values are strings.</param>892        /// <param name="result">Less than zero if first is smaller than second, more than  zero if it is greater or zero if they are the same.</param>893        /// <returns>True if the comparison was successful, false otherwise.</returns>894        /// <exception cref="ArgumentException">The parameter <paramref name="formatProvider"/> is not a <see cref="CultureInfo"/>.</exception>895        public static bool TryCompare(object first, object second, bool ignoreCase, IFormatProvider formatProvider, out int result)896        {897            result = 0;898            formatProvider ??= CultureInfo.InvariantCulture;899 900            if (formatProvider is not CultureInfo culture)901            {902                throw PSTraceSource.NewArgumentException(nameof(formatProvider));903            }904 905            first = PSObject.Base(first);906            second = PSObject.Base(second);907 908            if (first == null && second == null)909            {910                result = 0;911                return true;912            }913 914            if (first == null)915            {916                result = CompareObjectToNull(second, true);917                return true;918            }919 920            if (second == null)921            {922                // If it's a positive number, including 0, it's greater than null923                // for everything else it's less than zero...924                result = CompareObjectToNull(first, false);925                return true;926            }927 928            if (first is string firstString)929            {930                if (second is not string secondString)931                {932                    if (!TryConvertTo(second, culture, out secondString))933                    {934                        return false;935                    }936                }937 938                result = culture.CompareInfo.Compare(firstString, secondString, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);939                return true;940            }941 942            Type firstType = first.GetType();943            Type secondType = second.GetType();944            int firstIndex = TypeTableIndex(firstType);945            int secondIndex = TypeTableIndex(secondType);946            if (firstIndex != -1 && secondIndex != -1)947            {948                result = NumericCompare(first, second, firstIndex, secondIndex);949                return true;950            }951 952            if (!TryConvertTo(second, firstType, culture, out object secondConverted))953            {954                return false;955            }956 957            if (first is IComparable firstComparable)958            {959                result = firstComparable.CompareTo(secondConverted);960                return true;961            }962 963            if (first.Equals(second))964            {965                result = 0;966                return true;967            }968 969            // At this point, we know that they aren't equal but we have no way of970            // knowing which should compare greater than the other so we return false.971            return false;972        }973 974        /// <summary>975        /// Returns true if the language considers obj to be true.976        /// </summary>977        /// <param name="obj">Obj to verify if it is true.</param>978        /// <returns>True if obj is true.</returns>979        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "Since V1 code is already shipped, excluding this message for backward compatibility reasons")]980        public static bool IsTrue(object obj)981        {982            // null is a valid argument - it converts to false...983            if (obj == null || obj == AutomationNull.Value)984                return false;985 986            obj = PSObject.Base(obj);987 988            Type objType = obj.GetType();989 990            if (objType == typeof(bool))991            {992                return (bool)obj;993            }994 995            if (objType == typeof(string))996            {997                return IsTrue((string)obj);998            }999 1000            if (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(objType)))1001            {1002                IConversionData data = GetConversionData(objType, typeof(bool)) ??1003                                       CacheConversion(objType, typeof(bool), CreateNumericToBoolConverter(objType), ConversionRank.Language);1004                return (bool)data.Invoke(obj, typeof(bool), false, null, null, null);1005            }1006 1007            if (objType == typeof(SwitchParameter))1008                return ((SwitchParameter)obj).ToBool();1009 1010            IList objectArray = obj as IList;1011            if (objectArray != null)1012            {1013                return IsTrue(objectArray);1014            }1015 1016            return true;1017        }1018 1019        internal static bool IsTrue(string s)1020        {1021            return (s.Length != 0);1022        }1023 1024        internal static bool IsTrue(IList objectArray)1025        {1026            switch (objectArray.Count)1027            {1028                // a zero length array is false, so condition is false1029                case 0:1030                    return false;1031 1032                // if the result is an array of length 1, treat it as a scalar...1033                case 1:1034                    // A possible implementation would be just1035                    // return IsTrue(objectArray[0]);1036                    // but since we don't want this to recurse indefinitely1037                    // we explicitly check the case where it would recurse1038                    // and deal with it.1039                    if (PSObject.Base(objectArray[0]) is not IList firstElement)1040                    {1041                        return IsTrue(objectArray[0]);1042                    }1043 1044                    if (firstElement.Count < 1) return false;1045 1046                    // the first element is an array with more than zero elements1047                    return true;1048 1049                default:1050                    return true;1051            }1052        }1053 1054        /// <summary>1055        /// Internal routine that determines if an object meets any of our criteria for null.1056        /// </summary>1057        /// <param name="obj">The object to test.</param>1058        /// <returns>True if the object is null.</returns>1059        internal static bool IsNull(object obj)1060        {1061            return (obj == null || obj == AutomationNull.Value);1062        }1063 1064        /// <summary>1065        /// Auxiliary for the cases where we want a new PSObject or null.1066        /// </summary>1067        internal static PSObject AsPSObjectOrNull(object obj)1068        {1069            if (obj == null)1070            {1071                return null;1072            }1073 1074            return PSObject.AsPSObject(obj);1075        }1076 1077        internal static int TypeTableIndex(Type type)1078        {1079            switch (LanguagePrimitives.GetTypeCode(type))1080            {1081                case TypeCode.Int16: return 0;1082                case TypeCode.Int32: return 1;1083                case TypeCode.Int64: return 2;1084                case TypeCode.UInt16: return 3;1085                case TypeCode.UInt32: return 4;1086                case TypeCode.UInt64: return 5;1087                case TypeCode.SByte: return 6;1088                case TypeCode.Byte: return 7;1089                case TypeCode.Single: return 8;1090                case TypeCode.Double: return 9;1091                case TypeCode.Decimal: return 10;1092                default: return -1;1093            }1094        }1095 1096        /// <summary>1097        /// Table of the largest safe type to which both types can be converted without exceptions.1098        /// This table is used for numeric comparisons.1099        /// The 4 entries marked as not used, are explicitly dealt with in NumericCompareDecimal.1100        /// NumericCompareDecimal exists because doubles and singles can throw1101        /// an exception when converted to decimal.1102        /// The order of lines and columns cannot be changed since NumericCompare depends on it.1103        /// </summary>1104        internal static readonly Type[][] LargestTypeTable = new Type[][]1105        {1106            //                                       System.Int16            System.Int32            System.Int64            System.UInt16           System.UInt32           System.UInt64           System.SByte            System.Byte             System.Single           System.Double           System.Decimal1107            /* System.Int16   */new Type[] { typeof(System.Int16),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.Double),  typeof(System.Int16),   typeof(System.Int16),   typeof(System.Single),  typeof(System.Double),  typeof(System.Decimal) },1108            /* System.Int32   */new Type[] { typeof(System.Int32),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.Double),  typeof(System.Int32),   typeof(System.Int32),   typeof(System.Double),  typeof(System.Double),  typeof(System.Decimal) },1109            /* System.Int64   */new Type[] { typeof(System.Int64),   typeof(System.Int64),   typeof(System.Int64),   typeof(System.Int64),   typeof(System.Int64),   typeof(System.Decimal), typeof(System.Int64),   typeof(System.Int64),   typeof(System.Double),  typeof(System.Double),  typeof(System.Decimal) },1110            /* System.UInt16  */new Type[] { typeof(System.Int32),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.UInt16),  typeof(System.UInt32),  typeof(System.UInt64),  typeof(System.Int32),   typeof(System.UInt16),  typeof(System.Single),  typeof(System.Double),  typeof(System.Decimal) },1111            /* System.UInt32  */new Type[] { typeof(System.Int64),   typeof(System.Int64),   typeof(System.Int64),   typeof(System.UInt32),  typeof(System.UInt32),  typeof(System.UInt64),  typeof(System.Int64),   typeof(System.UInt32),  typeof(System.Double),  typeof(System.Double),  typeof(System.Decimal) },1112            /* System.UInt64  */new Type[] { typeof(System.Double),  typeof(System.Double),  typeof(System.Decimal), typeof(System.UInt64),  typeof(System.UInt64),  typeof(System.UInt64),  typeof(System.Double),  typeof(System.UInt64),  typeof(System.Double),  typeof(System.Double),  typeof(System.Decimal) },1113            /* System.SByte   */new Type[] { typeof(System.Int16),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.Double),  typeof(System.SByte),   typeof(System.Int16),   typeof(System.Single),  typeof(System.Double),  typeof(System.Decimal) },1114            /* System.Byte    */new Type[] { typeof(System.Int16),   typeof(System.Int32),   typeof(System.Int64),   typeof(System.UInt16),  typeof(System.UInt32),  typeof(System.UInt64),  typeof(System.Int16),   typeof(System.Byte),    typeof(System.Single),  typeof(System.Double),  typeof(System.Decimal) },1115            /* System.Single  */new Type[] { typeof(System.Single),  typeof(System.Double),  typeof(System.Double),  typeof(System.Single),  typeof(System.Double),  typeof(System.Double),  typeof(System.Single),  typeof(System.Single),  typeof(System.Single),  typeof(System.Double),  null/*not used*/       },1116            /* System.Double  */new Type[] { typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  typeof(System.Double),  null/*not used*/       },1117            /* System.Decimal */new Type[] { typeof(System.Decimal), typeof(System.Decimal), typeof(System.Decimal), typeof(System.Decimal), typeof(System.Decimal), typeof(System.Decimal), typeof(System.Decimal), typeof(System.Decimal), null/*not used*/,       null/*not used*/,       typeof(System.Decimal) },1118        };1119 1120        private static int NumericCompareDecimal(decimal decimalNumber, object otherNumber)1121        {1122            object otherDecimal = null;1123            try1124            {1125                otherDecimal = Convert.ChangeType(otherNumber, typeof(System.Decimal), CultureInfo.InvariantCulture);1126            }1127            catch (OverflowException)1128            {1129                try1130                {1131                    double wasDecimal = (double)Convert.ChangeType(decimalNumber, typeof(System.Double), CultureInfo.InvariantCulture);1132                    double otherDouble = (double)Convert.ChangeType(otherNumber, typeof(System.Double), CultureInfo.InvariantCulture);1133                    return ((IComparable)wasDecimal).CompareTo(otherDouble);1134                }1135                catch (Exception) // We need to catch the generic exception because ChangeType throws unadvertised exceptions1136                {1137                    return -1;1138                }1139            }1140            catch (Exception) // We need to catch the generic exception because ChangeType throws unadvertised exceptions1141            {1142                return -1;1143            }1144 1145            return ((IComparable)decimalNumber).CompareTo(otherDecimal);1146        }1147 1148        private static int NumericCompare(object number1, object number2, int index1, int index2)1149        {1150            // Conversion from single or double to decimal might throw1151            // if the double is greater than the decimal's maximum so1152            // we special case it in NumericCompareDecimal1153            if ((index1 == 10) && ((index2 == 8) || (index2 == 9)))1154            {1155                return NumericCompareDecimal((decimal)number1, number2);1156            }1157 1158            if ((index2 == 10) && ((index1 == 8) || (index1 == 9)))1159            {1160                return -NumericCompareDecimal((decimal)number2, number1);1161            }1162 1163            Type commonType = LargestTypeTable[index1][index2];1164            object number1Converted = Convert.ChangeType(number1, commonType, CultureInfo.InvariantCulture);1165            object number2Converted = Convert.ChangeType(number2, commonType, CultureInfo.InvariantCulture);1166            return ((IComparable)number1Converted).CompareTo(number2Converted);1167        }1168 1169        /// <summary>1170        /// Necessary not to return an integer type code for enums.1171        /// </summary>1172        /// <param name="type"></param>1173        /// <returns></returns>1174        internal static TypeCode GetTypeCode(Type type)1175        {1176            return type.GetTypeCode();1177        }1178 1179        /// <summary>1180        /// Emulates the "As" C# language primitive, but will unwrap1181        /// the PSObject if required.1182        /// </summary>1183        /// <typeparam name="T">The type for which to convert</typeparam>1184        /// <param name="castObject">The object from which to convert.</param>1185        /// <returns>An object of the specified type, if the conversion was successful.  Returns null otherwise.</returns>1186        internal static T FromObjectAs<T>(object castObject)1187        {1188            T returnType = default(T);1189 1190            // First, see if we can cast the direct type1191            PSObject wrapperObject = castObject as PSObject;1192            if (wrapperObject == null)1193            {1194                try1195                {1196                    returnType = (T)castObject;1197                }1198                catch (InvalidCastException)1199                {1200                    returnType = default(T);

Showing the first 1,200 of 5889 lines. Download the file for the rest.