internal System.Linq.Expressions.Expression ReduceTypeEqual() { System.Type type = this.Expression.Type; if (type.IsValueType && !type.IsNullableType()) { return(System.Linq.Expressions.Expression.Block(this.Expression, System.Linq.Expressions.Expression.Constant(type == this._typeOperand.GetNonNullableType()))); } if (this.Expression.NodeType == ExpressionType.Constant) { return(this.ReduceConstantTypeEqual()); } if (type.IsSealed && (type == this._typeOperand)) { if (type.IsNullableType()) { return(System.Linq.Expressions.Expression.NotEqual(this.Expression, System.Linq.Expressions.Expression.Constant(null, this.Expression.Type))); } return(System.Linq.Expressions.Expression.ReferenceNotEqual(this.Expression, System.Linq.Expressions.Expression.Constant(null, this.Expression.Type))); } ParameterExpression expression = this.Expression as ParameterExpression; if ((expression != null) && !expression.IsByRef) { return(this.ByValParameterTypeEqual(expression)); } expression = System.Linq.Expressions.Expression.Parameter(typeof(object)); System.Linq.Expressions.Expression expression2 = this.Expression; if (!TypeUtils.AreReferenceAssignable(typeof(object), expression2.Type)) { expression2 = System.Linq.Expressions.Expression.Convert(expression2, typeof(object)); } return(System.Linq.Expressions.Expression.Block(new ParameterExpression[] { expression }, new System.Linq.Expressions.Expression[] { System.Linq.Expressions.Expression.Assign(expression, expression2), this.ByValParameterTypeEqual(expression) })); }
public object Parse(string value, Type targetType) { if (targetType == null) throw new ArgumentNullException(nameof(targetType)); if(value == null) { if (targetType.IsNullableType()) return null; throw new ArgumentException($"Cannot parse null value as type {targetType}"); } targetType = Nullable.GetUnderlyingType(targetType) ?? targetType; try { if(!CanParseType(targetType)) throw new InvalidOperationException($"Cannot parse value, \"{value}\", and type, \"{targetType.FullName}\""); var enumValue = Enum.Parse(targetType, value); if(!Enum.IsDefined(targetType, enumValue)) throw new ArgumentException($"The enum, \"{targetType}\" does not define a value for \"{value}\""); return enumValue; } catch (ArgumentException) { throw new ArgumentOutOfRangeException( $"The value, \"{value}\" does not exist for enumeration, \"{targetType.FullName}\""); } }
public virtual Expression CreateReadValueExpression(Expression valueReader, Type type, int index) { Check.NotNull(valueReader, nameof(valueReader)); Check.NotNull(type, nameof(type)); var unwrappedTargetMemberType = type.UnwrapNullableType(); var underlyingTargetMemberType = unwrappedTargetMemberType.UnwrapEnumType(); var indexExpression = Expression.Constant(index); Expression readValueExpression = Expression.Call( valueReader, _readValue.MakeGenericMethod(underlyingTargetMemberType), indexExpression); if (underlyingTargetMemberType != type) { readValueExpression = Expression.Convert(readValueExpression, type); } if (type.IsNullableType()) { readValueExpression = Expression.Condition( Expression.Call(valueReader, _isNull, indexExpression), Expression.Constant(null, type), readValueExpression); } return readValueExpression; }
public override void InitDbParam(IDbDataParameter p, Type fieldType) { var sqlParam = (SqlParameter)p; sqlParam.SqlDbType = SqlDbType.Udt; sqlParam.IsNullable = fieldType.IsNullableType(); sqlParam.UdtTypeName = ColumnDefinition; }
private NumberJsonSerializer(Type type, bool encrypt) { _encrypt = encrypt; _nullable = type.IsNullableType(); _type = type; SetDelegates(out _write, out _read); }
internal static Type GetNullableType(Type type) { if (type.IsValueType && !type.IsNullableType()) { return typeof(Nullable<>).MakeGenericType(new Type[] { type }); } return type; }
public static IPropertyEditor TryCreate(Type type) { if (type.IsNullableType()) { return new NullablePropertyEditor(type); } return null; }
public override void InitDbParam(IDbDataParameter p, Type fieldType) { if (fieldType == typeof(SqlHierarchyId)) { var sqlParam = (SqlParameter)p; sqlParam.IsNullable = fieldType.IsNullableType(); sqlParam.SqlDbType = SqlDbType.Udt; sqlParam.UdtTypeName = ColumnDefinition; } base.InitDbParam(p, fieldType); }
private static System.Web.Routing.RouteValueDictionary ValueBoxHtmlAttributes(this System.Type type) { System.Type _type = type.IsNullableType() ? type.GetNonNullableType() : type; return(new System.Web.Routing.RouteValueDictionary { { "datatype", _type.FullName.Replace('.', '_') } }); }
public static ConditionalReceiver ConditionalReceiver(Type type) { ContractUtils.RequiresNotNull(type, nameof(type)); if (type == typeof(void) || type.IsByRef || type.IsNullableType()) { throw Error.InvalidConditionalReceiverType(type); } return new ConditionalReceiver(type); }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (targetType != null && targetType.IsNullableType()) { String strValue = value as String; if (strValue == String.Empty) { return null; } } return value; }
public DataRowFieldAccessExpressionBuilder(Type memberType, string memberName) : base(typeof(DataRow), memberName) { //Handle value types for null and DBNull.Value support converting them to Nullable<> if (memberType.IsValueType && !memberType.IsNullableType()) { this.columnDataType = typeof(Nullable<>).MakeGenericType(memberType); } else { this.columnDataType = memberType; } }
public static Type GetEnumerationType(Type enumType) { if (enumType.IsNullableType()) { enumType = enumType.GetTypeInfo().GenericTypeArguments[0]; } if (!enumType.IsEnum()) return null; return enumType; }
public static Type GetEnumerationType(Type enumType) { if (enumType.IsNullableType()) { enumType = enumType.GetGenericArguments()[0]; } if (!enumType.IsEnum) return null; return enumType; }
public static IPropertyEditor TryCreate(Type type, ICustomAttributeProvider attributes) { if (type.IsNullableType()) { return new NullablePropertyEditor(type.GetGenericArguments()[0]); } if (attributes != null && type.IsClass && attributes.IsDefined(typeof(InspectorNullableAttribute), /*inherit:*/true)) { return new NullablePropertyEditor(type); } return null; }
public static object ChangeType(object value, Type conversionType, CultureInfo cultureInfo) { if (value == DBNull.Value) value = null; if (value == null || value.Equals("")) { if (conversionType == typeof(DateTime)) return typeof(Nullable).IsAssignableFrom(conversionType) ? (object)null : DateTime.MinValue; if (conversionType == typeof(int) || conversionType == typeof(double)) return typeof(Nullable).IsAssignableFrom(conversionType) ? (object)null : 0; if (conversionType == typeof(bool)) return typeof(Nullable).IsAssignableFrom(conversionType) ? (object)null : false; if (typeof(IEnumerable).IsAssignableFrom(conversionType) && string.IsNullOrEmpty(value + "")) return null; if (conversionType.IsValueType) return conversionType.CreateInstance(); } else if (typeof(Enum).IsAssignableFrom(conversionType)) return Enum.Parse(conversionType, (string)value); else if ((value + "").IsGuid() && conversionType == typeof(Guid)) return new Guid(value.ToString()); else if (value.GetType() == conversionType) return value; else { var o = value as XPBaseObject; if (o != null) { if (conversionType == typeof(int)) return o.ClassInfo.KeyProperty.GetValue(o); if (conversionType == typeof(string)) return o.ClassInfo.KeyProperty.GetValue(o).ToString(); return value; } if (conversionType == typeof(DateTime)) { if ((value + "").Length > 0) { var val = (value + "").Val(); if (val > 0) return new DateTime(val); } } else if (value.GetType() != conversionType) { if (conversionType.IsNullableType()) { return ChangeType(value, conversionType.GetGenericArguments()[0], cultureInfo); } if (conversionType.IsGenericType) { return value; } } } return Convert.ChangeType(value, conversionType, cultureInfo); }
private Type GetPropertyType(Type memberType) { var descriptorProviderPropertyType = this.GetPropertyTypeFromTypeDescriptorProvider(); if (descriptorProviderPropertyType != null) { memberType = descriptorProviderPropertyType; } //Handle value types for null and DBNull.Value support converting them to Nullable<> if (memberType.IsValueType && !memberType.IsNullableType()) { return typeof(Nullable<>).MakeGenericType(memberType); } return memberType; }
public TypeInfo GetTypeInfoInner(Type type) { if (type.IsNullableType()) { var baseType = type.GenericTypeArguments[0]; return GetTypeInfo(baseType); } Type genericElementType = null; string typescriptName; if (TryGetTypeName(type.FullName, out typescriptName)) { return new TypeInfo(typescriptName, string.Empty); } if (type.TryGetGenericCollectionType(out genericElementType)) { var typeInfo = GetTypeInfo(genericElementType); var arrayResult = new TypeInfo(typeInfo.Name + "[]", typeInfo.NameSpaceName); return arrayResult; } if (type.IsDictionaryType()) { return TypeScriptLanguage.any; } if (type.IsEnum) { return new TypeInfo("number", string.Empty); } //* if (!type.IsExportableType()) { return TypeScriptLanguage.any; } //*/ // for now, uses a C# style for anything else string typeName = type.FullName.Replace(type.Namespace + ".", ""); var typeReference = new System.CodeDom.CodeTypeReference(typeName); var nameSpace = type.Namespace != "System" ? type.Namespace : ""; return new TypeInfo(typeName, nameSpace); }
/// <summary> /// Use this instead of <see cref="Convert.ChangeType"/> to support /// <see cref="Nullable<>"/> types. Returns an <see cref="Object"/> with the specified /// <see cref="Type"/> of which the value is equivelant to the specified object. /// </summary> /// <param name="obj">Specifies the object for which the type should change.</param> /// <param name="toType">Specifies the type to change the specified object to.</param> /// <returns>The specified object, converted to the specified type.</returns> public static object ChangeType(this object obj, Type toType) { if (obj.IsNullableType()) { if (obj == null) return null; NullableConverter oConverter = new NullableConverter(obj.GetType()); toType = oConverter.UnderlyingType; } else if (toType.IsNullableType()) { if (obj == null) return null; NullableConverter converter = new NullableConverter(toType); toType = converter.UnderlyingType; } return Convert.ChangeType(obj, toType); }
/// <summary> /// Use this instead of <see cref="Convert.ChangeType"/> to support /// <see cref="Nullable<>"/> types. Returns an <see cref="Object"/> with the specified /// <see cref="Type"/> of which the value is equivalent to the specified object. /// </summary> /// <param name="obj">Specifies the object for which the type should change.</param> /// <param name="toType">Specifies the type to change the specified object to.</param> /// <returns>The specified object, converted to the specified type.</returns> public static object ChangeType(this object obj, Type toType) { Contract.Requires<ArgumentNullException>(obj != null, "obj is null"); Contract.Requires<ArgumentNullException>(toType != null, "toType is null"); var objType = obj.GetType(); if (obj.IsNullableType()) { if (obj == null) return null; NullableConverter oConverter = new NullableConverter(objType); toType = oConverter.UnderlyingType; } else if (toType.IsNullableType()) { if (obj == null) return null; NullableConverter converter = new NullableConverter(toType); toType = converter.UnderlyingType; } if (toType != null) { if (obj is IConvertible) { return Convert.ChangeType(obj, toType); } if (toType.IsAssignableFrom(objType)) { return obj; } } throw new InvalidOperationException(string.Format( "Cannot convert {0} to {1}", objType, toType)); }
public virtual Expression CreateReadValueExpression(Expression valueBuffer, Type type, int index) { Expression expression = Expression.Call(valueBuffer, _readValue, Expression.Constant(index)); if (type.IsNullableType()) { var underlyingType = type.UnwrapNullableType(); if (underlyingType.GetTypeInfo().IsEnum) { return Expression.Condition( Expression.ReferenceEqual( expression, Expression.Constant(null)), Expression.Constant(null, type), Expression.Convert( Expression.Convert( expression, underlyingType.UnwrapEnumType()), type)); } } return Expression.Convert(expression, type); }
private static string GetModelTypeName(Type modelType, string path = null, string verb = null) { if (modelType.IsValueType || modelType.IsNullableType()) return SwaggerType.String; verb = string.IsNullOrEmpty(verb) ? "" : verb + "_"; if (!modelType.IsGenericType) return verb + modelType.Name + (path ?? ""); var modelTypeName = modelType.FullName.Replace("`1[[", "`").Replace(modelType.Namespace + ".", ""); var index = modelTypeName.IndexOf(",", StringComparison.Ordinal); var genericNamespace = modelType.GenericTypeArguments()[0].Namespace + "."; return verb + modelTypeName.Substring(0, index).Replace(genericNamespace, "") + "`" + (path ?? ""); }
private static bool IsSwaggerScalarType(Type type) { return ClrTypesToSwaggerScalarTypes.ContainsKey(type) || (Nullable.GetUnderlyingType(type) ?? type).IsEnum || type.IsValueType || type.IsNullableType(); }
bool InnerTryConvert(Type returnType, out object result) { if (returnType == typeof(object)) { result = this; return true; } if (returnType.IsNullableType()) { returnType = Nullable.GetUnderlyingType(returnType); } switch (Type) { case JsonObjectType.False: result = false; return returnType == typeof(bool); case JsonObjectType.True: result = true; return returnType == typeof(bool); case JsonObjectType.FastNumber: if (returnType == typeof(double)) { double res; var ret = FastNumberToDouble(out res); result = res; return ret; } if (returnType == typeof(float)) { float res; var ret = FastNumberToFloat(out res); result = res; return ret; } if (returnType == typeof(decimal)) { decimal res; var ret = FastNumberToDecimal(out res); result = res; return ret; } if (returnType == typeof(byte)) { byte res; var ret = FastNumberToByte(out res); result = res; return ret; } if (returnType == typeof(sbyte)) { sbyte res; var ret = FastNumberToSByte(out res); result = res; return ret; } if (returnType == typeof(short)) { short res; var ret = FastNumberToShort(out res); result = res; return ret; } if (returnType == typeof(ushort)) { ushort res; var ret = FastNumberToUShort(out res); result = res; return ret; } if (returnType == typeof(int)) { int res; var ret = FastNumberToInt(out res); result = res; return ret; } if (returnType == typeof(uint)) { uint res; var ret = FastNumberToUInt(out res); result = res; return ret; } if (returnType == typeof(long)) { long res; var ret = FastNumberToLong(out res); result = res; return ret; } if (returnType == typeof(ulong)) { ulong res; var ret = FastNumberToULong(out res); result = res; return ret; } if (returnType == typeof(DateTime)) { long res; var ret = FastNumberToLong(out res); if (!ret) { result = null; return false; } switch(Options.UseDateTimeFormat) { case DateTimeFormat.MillisecondsSinceUnixEpoch: result = Methods.UnixEpoch + TimeSpan.FromMilliseconds(res); return true; case DateTimeFormat.SecondsSinceUnixEpoch: result = Methods.UnixEpoch + TimeSpan.FromSeconds(res); return true; default: result = null; return false; } } if(returnType == typeof(DateTimeOffset)) { long res; var ret = FastNumberToLong(out res); if (!ret) { result = null; return false; } switch (Options.UseDateTimeFormat) { case DateTimeFormat.MillisecondsSinceUnixEpoch: result = Methods.UnixEpochOffset + TimeSpan.FromMilliseconds(res); return true; case DateTimeFormat.SecondsSinceUnixEpoch: result = Methods.UnixEpochOffset + TimeSpan.FromSeconds(res); return true; default: result = null; return false; } } if(returnType == typeof(TimeSpan)) { const double TicksPerMillisecond = 10000; const double TicksPerSecond = 10000000; double res; var ret = FastNumberToDouble(out res); if (!ret) { result = null; return false; } switch (Options.UseDateTimeFormat) { case DateTimeFormat.MillisecondsSinceUnixEpoch: var msTicksDouble = res * TicksPerMillisecond; var msTicks = (long)msTicksDouble; if (msTicksDouble >= TimeSpan.MaxValue.Ticks) { msTicks = TimeSpan.MaxValue.Ticks; } if(msTicksDouble <= TimeSpan.MinValue.Ticks) { msTicks = TimeSpan.MinValue.Ticks; } result = new TimeSpan(msTicks); return true; case DateTimeFormat.SecondsSinceUnixEpoch: var sTicksDouble = res * TicksPerSecond; var sTicks = (long)sTicksDouble; if (sTicksDouble >= TimeSpan.MaxValue.Ticks) { sTicks = TimeSpan.MaxValue.Ticks; } if(sTicksDouble <= TimeSpan.MinValue.Ticks) { sTicks = TimeSpan.MinValue.Ticks; } result = new TimeSpan(sTicks); return true; default: result = null; return false; } } break; case JsonObjectType.Number: if (returnType == typeof(double)) { result = NumberValue; return true; } if (returnType == typeof(float)) { result = (float)NumberValue; return true; } if (returnType == typeof(decimal)) { result = (decimal)NumberValue; return true; } if (returnType == typeof(byte)) { result = (byte)NumberValue; return true; } if (returnType == typeof(sbyte)) { result = (sbyte)NumberValue; return true; } if (returnType == typeof(short)) { result = (short)NumberValue; return true; } if (returnType == typeof(ushort)) { result = (ushort)NumberValue; return true; } if (returnType == typeof(int)) { result = (int)NumberValue; return true; } if (returnType == typeof(uint)) { result = (uint)NumberValue; return true; } if (returnType == typeof(long)) { result = (long)NumberValue; return true; } if (returnType == typeof(ulong)) { result = (ulong)NumberValue; return true; } if (returnType == typeof(DateTime)) { var res = (long)NumberValue; switch (Options.UseDateTimeFormat) { case DateTimeFormat.MillisecondsSinceUnixEpoch: result = Methods.UnixEpoch + TimeSpan.FromMilliseconds(res); return true; case DateTimeFormat.SecondsSinceUnixEpoch: result = Methods.UnixEpoch + TimeSpan.FromSeconds(res); return true; default: result = null; return false; } } if (returnType == typeof(DateTimeOffset)) { var res = (long)NumberValue; switch (Options.UseDateTimeFormat) { case DateTimeFormat.MillisecondsSinceUnixEpoch: result = Methods.UnixEpochOffset + TimeSpan.FromMilliseconds(res); return true; case DateTimeFormat.SecondsSinceUnixEpoch: result = Methods.UnixEpochOffset + TimeSpan.FromSeconds(res); return true; default: result = null; return false; } } if (returnType == typeof(TimeSpan)) { const double TicksPerMillisecond = 10000; const double TicksPerSecond = 10000000; var res = NumberValue; switch (Options.UseDateTimeFormat) { case DateTimeFormat.MillisecondsSinceUnixEpoch: var msTicksDouble = res * TicksPerMillisecond; var msTicks = (long)msTicksDouble; if (msTicksDouble >= TimeSpan.MaxValue.Ticks) { msTicks = TimeSpan.MaxValue.Ticks; } if (msTicksDouble <= TimeSpan.MinValue.Ticks) { msTicks = TimeSpan.MinValue.Ticks; } result = new TimeSpan(msTicks); return true; case DateTimeFormat.SecondsSinceUnixEpoch: var sTicksDouble = res * TicksPerSecond; var sTicks = (long)sTicksDouble; if (sTicksDouble >= TimeSpan.MaxValue.Ticks) { sTicks = TimeSpan.MaxValue.Ticks; } if (sTicksDouble <= TimeSpan.MinValue.Ticks) { sTicks = TimeSpan.MinValue.Ticks; } result = new TimeSpan(sTicks); return true; default: result = null; return false; } } break; case JsonObjectType.String: if (returnType == typeof(string)) { result = StringValue; return true; } if (returnType.IsEnum()) { if (returnType.IsFlagsEnum()) { return ParseFlagsEnum(returnType, out result); } return EnumValues.TryParse(returnType, StringValue, out result); } if (returnType == typeof(Guid)) { Guid guid; if (!Guid.TryParseExact(StringValue, "D", out guid)) { result = null; return false; } result = guid; return true; } if (returnType == typeof(DateTime)) { DateTime res; bool ret; switch(Options.UseDateTimeFormat) { case DateTimeFormat.MicrosoftStyleMillisecondsSinceUnixEpoch: ret = Methods.ReadMicrosoftStyleDateTime(StringValue, out res); result = res; return ret; case DateTimeFormat.ISO8601: ret = Methods.ReadISO8601DateTime(StringValue, out res); result = res; return ret; case DateTimeFormat.RFC1123: ret = Methods.ReadRFC1123DateTime(StringValue, out res); result = res; return ret; default: result = null; return false; } } if (returnType == typeof(DateTimeOffset)) { DateTime dt; DateTimeOffset res; bool ret; switch (Options.UseDateTimeFormat) { case DateTimeFormat.MicrosoftStyleMillisecondsSinceUnixEpoch: ret = Methods.ReadMicrosoftStyleDateTime(StringValue, out dt); res = dt; result = res; return ret; case DateTimeFormat.ISO8601: ret = Methods.ReadISO8601DateWithOffset(StringValue, out res); result = res; return ret; default: result = null; return false; } } if(returnType == typeof(TimeSpan)) { TimeSpan ts; bool ret; switch (Options.UseDateTimeFormat) { case DateTimeFormat.MicrosoftStyleMillisecondsSinceUnixEpoch: ret = Methods.ReadMicrosoftStyleTimeSpan(StringValue, out ts); result = ts; return ret; case DateTimeFormat.ISO8601: ret = Methods.ReadISO8601TimeSpan(StringValue, out ts); result = ts; return ret; default: result = null; return false; } } break; case JsonObjectType.Object: if (returnType == typeof(System.Collections.IEnumerable)) { result = EnumerableObjectWrapper.MakeAsIEnumerable(ObjectMembers); return true; } if (returnType.IsGenericDictionary()) { var args = returnType.GetGenericArguments(); var keyType = args[0]; var valType = args[1]; var stringKeys = keyType == typeof(string); var enumKeys = keyType.IsEnum(); // only strings and enums can be keys if (!(stringKeys || enumKeys)) { result = null; return false; } var coerced = new Dictionary<object, object>(ObjectMembers.Count); foreach (var kv in ObjectMembers) { object innerResult = null; if (kv.Value != null && !kv.Value.InnerTryConvert(valType, out innerResult)) { result = null; return false; } if (stringKeys) { coerced[kv.Key] = innerResult; } else { object @enum = Enum.Parse(keyType, kv.Key, ignoreCase: true); coerced[@enum] = innerResult; } } if (stringKeys) { result = Utils.ProjectStringDictionary(coerced, valType); } else { // enum keys result = Utils.ProjectEnumDictionary(coerced, keyType, valType); } return true; } break; case JsonObjectType.Array: if (returnType == typeof(System.Collections.IEnumerable)) { result = EnumerableArrayWrapper.MakeAsIEnumerable(ArrayValue); return true; } if (returnType.IsGenericEnumerable()) { var castTo = returnType.GetGenericArguments()[0]; if (castTo == typeof(object)) { result = EnumerableArrayWrapper.MakeAsIEnumerableOfT(ArrayValue); return true; } bool bail = false; var dynamicProjection = ArrayValue.Select( val => { object innerResult; if (!val.InnerTryConvert(castTo, out innerResult)) { bail = true; return Activator.CreateInstance(castTo); } return innerResult; } ); result = Utils.DynamicProject(dynamicProjection, castTo); if (bail) { result = null; return false; } return true; } break; } result = null; return false; }
public static Type MakeNullable(this Type type) => type.IsNullableType() ? type : typeof(Nullable <>).MakeGenericType(type);
object GetObjectOfTypeFromNode(Type t, XmlNode node) { if (t.IsSimpleType() || t == typeof(Uri) || t.IsNullableType()) { return GetPropertyValue(t, node); } if (typeof(IEnumerable).IsAssignableFrom(t)) { return GetPropertyValue(t, node); } var result = mapper.CreateInstance(t); foreach (XmlNode n in node.ChildNodes) { Type type = null; if (n.Name.Contains(":")) { type = Type.GetType($"System.{n.Name.Substring(0, n.Name.IndexOf(":"))}", false, true); } var prop = GetProperty(t, n.Name); if (prop != null) { var val = GetPropertyValue(type ?? prop.PropertyType, n); if (val != null) { var propertySet = DelegateFactory.CreateSet(prop); propertySet.Invoke(result, val); continue; } } var field = GetField(t, n.Name); if (field != null) { var val = GetPropertyValue(type ?? field.FieldType, n); if (val != null) { var fieldSet = DelegateFactory.CreateSet(field); fieldSet.Invoke(result, val); } } } return result; }
/// <summary> /// 对类型进行精确推断。 /// </summary> /// <param name="paramType">形参类型。</param> /// <param name="type">实参类型。</param> /// <param name="boundSets">泛型形参的界限集。</param> /// <returns>如果精确推断成功,则为 <c>true</c>;否则为 <c>false</c>。</returns> private static bool ExactInferences(Type paramType, Type type, Dictionary<Type, BoundSet> boundSets) { Type tempParamType; if (paramType.IsGenericParameter) { return boundSets[paramType].AddExactBound(type); } else if (paramType.IsNullableType(out tempParamType)) { Type tempType; if (type.IsNullableType(out tempType)) { return ExactInferences(tempParamType, tempType, boundSets); } } else if (paramType.IsArray) { if (type.IsArray && paramType.GetArrayRank() == type.GetArrayRank()) { return LowerBoundInferences(paramType.GetElementType(), type.GetElementType(), boundSets); } } else if (paramType.GetGenericTypeDefinition() == type.GetGenericTypeDefinition()) { Type[] paramTypeArgs = paramType.GetGenericArguments(); Type[] typeArgs = type.GetGenericArguments(); for (int i = 0; i < paramTypeArgs.Length; i++) { if (!ExactInferences(paramTypeArgs[i], typeArgs[i], boundSets)) { return false; } } } return true; }
internal static string GetClrUserDefinedTypeName(Type type) { //string schemaName = ((argInfo != null) && !String.IsNullOrEmpty(argInfo.SchemaName)) ? argInfo.SchemaName.Replace("[", "").Replace("]", "") : "dbo"; #warning check schemaname handling on GetClrUserDefinedTypeName string schemaName = "dbo"; Type clrType = type.IsNullableType() ? type.GetGenericArguments()[0] : type; SqlUserDefinedTypeAttribute[] attributes = (SqlUserDefinedTypeAttribute[])clrType.GetCustomAttributes(typeof(SqlUserDefinedTypeAttribute), false); if (attributes.Length > 0) { string typeName = attributes[0].Name.Replace("[", "").Replace("]", ""); return String.Format("[{0}].[{1}]", schemaName, typeName); } return String.Empty; }
/// <summary> /// 获取Nullable-T-的泛型参数类型 /// </summary> public static Type GetNullableGenericType(this Type @type) { return(@type.IsNullableType() ? type.GetGenericArguments()[0] : @type); }
// Binary/unary operations on 8 and 16 bit operand types will leave a // 32-bit value on the stack, because that's how IL works. For these // cases, we need to cast it back to the resultType, possibly using a // checked conversion if the original operator was convert private void EmitConvertArithmeticResult(ExpressionType op, Type resultType) { Debug.Assert(!resultType.IsNullableType()); switch (Type.GetTypeCode(resultType)) { case TypeCode.Byte: _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_U1 : OpCodes.Conv_U1); break; case TypeCode.SByte: _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_I1 : OpCodes.Conv_I1); break; case TypeCode.UInt16: _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_U2 : OpCodes.Conv_U2); break; case TypeCode.Int16: _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_I2 : OpCodes.Conv_I2); break; } }
public static Type MakeNullable(this Type type, bool nullable = true) => type.IsNullableType() == nullable ? type : nullable ? typeof(Nullable <>).MakeGenericType(type) : type.UnwrapNullableType();
private static Type GetResultTypeOfShift(Type left, Type right) { if (!left.IsNullableType() && right.IsNullableType()) { // lift the result type to Nullable<T> return typeof(Nullable<>).MakeGenericType(left); } return left; }
/// <summary> /// 对类型进行上限推断。 /// </summary> /// <param name="paramType">形参类型。</param> /// <param name="type">实参类型。</param> /// <param name="boundSets">泛型形参的界限集。</param> /// <returns>如果上限推断成功,则为 <c>true</c>;否则为 <c>false</c>。</returns> private static bool UpperBoundInferences(Type paramType, Type type, Dictionary<Type, BoundSet> boundSets) { Type tempParamType = null, tempType = null; if (paramType.IsGenericParameter) { return boundSets[paramType].AddUpperBound(type); } else if (paramType.IsNullableType(out tempParamType)) { if (type.IsNullableType(out tempType)) { return UpperBoundInferences(tempParamType, tempType, boundSets); } } else if (paramType.IsArray) { tempParamType = paramType.GetElementType(); if (type.IsArray) { if (paramType.GetArrayRank() == type.GetArrayRank()) { return UpperBoundInferences(tempParamType, type.GetElementType(), boundSets); } } else if (type.IsGenericType) { tempType = type.GetGenericTypeDefinition(); if (tempType == typeof(IList<>) || tempType == typeof(ICollection<>) || tempType == typeof(IEnumerable<>)) { return UpperBoundInferences(tempParamType, tempType.GetGenericArguments()[0], boundSets); } } } else if (type.IsGenericType) { tempType = type.GetGenericTypeDefinition(); if (tempType.UniqueOpenGenericIsAssignableFrom(paramType, out tempParamType)) { Type[] originArgs = tempType.GetGenericArguments(); Type[] paramTypeArgs = tempParamType.GetGenericArguments(); Type[] typeArgs = type.GetGenericArguments(); for (int i = 0; i < originArgs.Length; i++) { bool result = true; switch (originArgs[i].GenericParameterAttributes & GenericParameterAttributes.VarianceMask) { case GenericParameterAttributes.None: result = ExactInferences(paramTypeArgs[i], typeArgs[i], boundSets); break; case GenericParameterAttributes.Covariant: result = UpperBoundInferences(paramTypeArgs[i], typeArgs[i], boundSets); break; case GenericParameterAttributes.Contravariant: result = LowerBoundInferences(paramTypeArgs[i], typeArgs[i], boundSets); break; } if (!result) { return false; } } } } return true; }
///////////////////////////////////////////////////////////////////////////////// private CType ProcessSpecialTypeInChain(NamespaceOrAggregateSymbol parent, Type t) { CType ctype; if (t.IsGenericParameter) { AggregateSymbol agg = parent as AggregateSymbol; Debug.Assert(agg != null); ctype = LoadClassTypeParameter(agg, t); return ctype; } else if (t.IsArray) { // Now we return an array of nesting level corresponding to the rank. ctype = _typeManager.GetArray(GetCTypeFromType(t.GetElementType()), t.GetArrayRank()); return ctype; } else if (t.IsPointer) { // Now we return the pointer type that we want. ctype = _typeManager.GetPointer(GetCTypeFromType(t.GetElementType())); return ctype; } else if (t.IsNullableType()) { // Get a nullable type of the underlying type. if (t.GetGenericArguments()[0].DeclaringType == t) { // If the generic argument for nullable is our child, then we're // declaring the initial Nullable<T>. AggregateSymbol agg = _symbolTable.LookupSym( GetName(t), parent, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol(); if (agg != null) { agg = FindSymWithMatchingArity(agg, t); if (agg != null) { Debug.Assert(agg.getThisType().AssociatedSystemType == t); return agg.getThisType(); } } return AddAggregateToSymbolTable(parent, t).getThisType(); } ctype = _typeManager.GetNullable(GetCTypeFromType(t.GetGenericArguments()[0])); return ctype; } return null; }
/// <summary> /// Gets the most common type between two. /// </summary> private static Type getMostCommonType(Type left, Type right) { // corner case if (left == null || left == right) return right; if (right.IsInterface) return typeof (object); // valuetype & null if (left == typeof (NullType) && right.IsValueType) return typeof (Nullable<>).MakeGenericType(right); if (right == typeof(NullType) && left.IsValueType) return typeof(Nullable<>).MakeGenericType(left); // valuetype & Nullable<valuetype> if (left.IsNullableType() && left.GetGenericArguments()[0] == right) return left; if (right.IsNullableType() && right.GetGenericArguments()[0] == left) return right; // numeric extensions if (left.IsNumericType() && right.IsNumericType()) return GetNumericOperationType(left, right) ?? typeof(object); // arrays if (left.IsArray && right.IsArray) { var leftElem = left.GetElementType(); var rightElem = right.GetElementType(); return leftElem.IsValueType || rightElem.IsValueType ? typeof (object) : getMostCommonType(leftElem, rightElem).MakeArrayType(); } // inheritance var currLeft = left; while (currLeft != null) { var currRight = right; while (currRight != null) { if (currLeft == currRight) return currLeft; currRight = currRight.BaseType; } currLeft = currLeft.BaseType; } return typeof(object); }