/// <summary> /// Serializes a nullable enumerated value. /// </summary> public NullableEnumSerializer(Type EnumType) { this.enumType = EnumType; this.genericType = typeof(Nullable <>).MakeGenericType(this.enumType); this.constructor = null; foreach (ConstructorInfo CI in this.genericType.GetTypeInfo().DeclaredConstructors) { ParameterInfo[] P = CI.GetParameters(); if (P.Length == 1 && P[0].ParameterType == this.enumType) { this.constructor = CI; break; } } if (this.constructor is null) { throw new ArgumentException("Generic nullable type lacks required constructor.", nameof(EnumType)); } this.valueProperty = this.genericType.GetRuntimeProperty("Value"); if (this.valueProperty is null) { throw new ArgumentException("Generic nullable type lacks required Value property.", nameof(EnumType)); } }
/// <summary> /// Maintains a set of serializers. /// </summary> /// <param name="Context">Serialization context.</param> public SerializerCollection(ISerializerContext Context) #endif { this.context = Context; this.serializers = new Dictionary <Type, IObjectSerializer>(); #if NETSTANDARD1_5 this.compiled = Compiled; #endif ConstructorInfo DefaultConstructor; IObjectSerializer S; TypeInfo TI; foreach (Type T in Types.GetTypesImplementingInterface(typeof(IObjectSerializer))) { TI = T.GetTypeInfo(); if (TI.IsAbstract || TI.IsGenericTypeDefinition) { continue; } DefaultConstructor = null; try { foreach (ConstructorInfo CI in TI.DeclaredConstructors) { if (CI.IsPublic && CI.GetParameters().Length == 0) { DefaultConstructor = CI; break; } } if (DefaultConstructor is null) { continue; } S = DefaultConstructor.Invoke(Types.NoParameters) as IObjectSerializer; if (S is null) { continue; } } catch (Exception) { continue; } this.serializers[S.ValueType] = S; } this.serializers[typeof(GenericObject)] = new GenericObjectSerializer(this.context, false); this.serializers[typeof(object)] = new GenericObjectSerializer(this.context, true); }
/// <summary> /// Nullable property /// </summary> public NullableProperty(Type NullableType, Type ElementType, IProperty Element) : base() { this.nullableType = NullableType; this.elementType = ElementType; this.element = Element; this.constructor = null; foreach (ConstructorInfo CI in this.nullableType.GetTypeInfo().DeclaredConstructors) { ParameterInfo[] P = CI.GetParameters(); if (P.Length == 1 && P[0].ParameterType == this.elementType) { this.constructor = CI; break; } } this.valueProperty = this.nullableType.GetRuntimeProperty("Value"); }
/// <summary> /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection. /// </summary> /// <param name="Variables">Variables collection.</param> /// <returns>Result.</returns> public override IElement Evaluate(Variables Variables) { IElement E = this.type.Evaluate(Variables); TypeValue TV = E as TypeValue; if (TV == null) { throw new ScriptRuntimeException("First argument must evaluate to the type to be created.", this); } IElement[] Arguments = null; ParameterInfo[] Parameters; object[] ParameterValues; object Value; int i, c; lock (this.synchObject) { if (this.lastType == TV.Value && this.lastGenericType != null) { c = this.genericArguments.Length; if (this.nrParameters < c) { throw new ScriptRuntimeException("Expected " + c.ToString() + " generic type arguments.", this); } for (i = 0; i < c; i++) { E = this.parameters[i].Evaluate(Variables); TV = E as TypeValue; if (TV == null) { throw new ScriptRuntimeException("Generic type arguments must evaluate to types to be sed.", this); } if (this.genericArguments[i] != TV.Value) { this.lastType = null; this.lastGenericType = null; this.genericArguments = null; this.constructor = null; break; } } } if (this.lastType != TV.Value) { Type T = TV.Value; this.constructor = null; if (T.GetTypeInfo().ContainsGenericParameters) { this.genericArguments = T.GetTypeInfo().GenericTypeParameters; c = this.genericArguments.Length; if (this.nrParameters < c) { throw new ScriptRuntimeException("Expected " + c.ToString() + " generic type arguments.", this); } for (i = 0; i < c; i++) { E = this.parameters[i].Evaluate(Variables); TV = E as TypeValue; if (TV == null) { throw new ScriptRuntimeException("Generic type arguments must evaluate to types to be sed.", this); } this.genericArguments[i] = TV.Value; } this.lastGenericType = T.MakeGenericType(this.genericArguments); } else { this.genericArguments = null; this.lastGenericType = null; c = 0; } this.lastType = TV.Value; this.constructor = null; } else if (this.genericArguments != null) { c = this.genericArguments.Length; } else { c = 0; } Arguments = new IElement[this.nrParameters - c]; for (i = c; i < this.nrParameters; i++) { Arguments[i - c] = this.parameters[i].Evaluate(Variables); } if (this.constructor != null) { if (this.constructorParametersTypes.Length != this.nrParameters - c) { this.constructor = null; } else { for (i = c; i < this.constructorParametersTypes.Length; i++) { if (!Arguments[i].TryConvertTo(this.constructorParametersTypes[i].ParameterType, out Value)) { break; } this.constructorArguments[i] = Value; } if (i < this.constructorParametersTypes.Length) { this.constructor = null; } } } if (this.constructor == null) { IEnumerable <ConstructorInfo> Constructors; if (this.lastGenericType != null) { Constructors = this.lastGenericType.GetTypeInfo().DeclaredConstructors; } else { Constructors = this.lastType.GetTypeInfo().DeclaredConstructors; } ParameterValues = null; foreach (ConstructorInfo CI in Constructors) { Parameters = CI.GetParameters(); if (Parameters.Length != this.nrParameters - c) { continue; } for (i = c; i < Parameters.Length; i++) { if (!Arguments[i].TryConvertTo(Parameters[i].ParameterType, out Value)) { break; } if (ParameterValues == null) { ParameterValues = new object[Parameters.Length]; } ParameterValues[i] = Value; } if (i < Parameters.Length) { continue; } this.constructor = CI; this.constructorParametersTypes = Parameters; this.constructorArguments = ParameterValues; break; } if (this.constructor == null) { throw new ScriptRuntimeException("Invalid number or type of parameters.", this); } } } return(Expression.Encapsulate(this.constructor.Invoke(this.constructorArguments))); }