private Union CreateUnion(Type t) { Union u = new Union(); u.TagReader = FSharpFunc <object, int> .ToConverter(FSharpValue.PreComputeUnionTagReader(t, null)); u.Cases = new List <UnionCase>(); UnionCaseInfo[] cases = FSharpType.GetUnionCases(t, null); foreach (UnionCaseInfo unionCaseInfo in cases) { UnionCase unionCase = new UnionCase(); unionCase.Tag = unionCaseInfo.Tag; unionCase.Name = unionCaseInfo.Name; unionCase.Fields = unionCaseInfo.GetFields(); unionCase.FieldReader = FSharpFunc <object, object[]> .ToConverter(FSharpValue.PreComputeUnionReader(unionCaseInfo, null)); unionCase.Constructor = FSharpFunc <object[], object> .ToConverter(FSharpValue.PreComputeUnionConstructor(unionCaseInfo, null)); u.Cases.Add(unionCase); } return(u); }
public IValueInterface <T> TryMap <T>() { if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(FSharpList <>)) { var elementType = typeof(T).GetGenericArguments()[0]; return((IValueInterface <T>)Activator.CreateInstance(typeof(FSharpListInterface <>).MakeGenericType(elementType))); } if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(FSharpOption <>)) { var elementType = typeof(T).GetGenericArguments()[0]; return((IValueInterface <T>)Activator.CreateInstance(typeof(FSharpOptionInterface <>).MakeGenericType(elementType))); } if (FSharpType.IsUnion(typeof(T), AllBindingFlags)) { return(new FSharpUnionInterface <T>()); } if (FSharpType.IsRecord(typeof(T), AllBindingFlags)) { FastObjectRW <T> .CurrentOptions |= FastObjectRWOptions.Allocate | FastObjectRWOptions.AutoPropertyDirectRW; XObjectInterface <T> .DefaultBindingFlags |= XBindingFlags.RWAllocate | XBindingFlags.RWAutoPropertyDirectRW; } return(null); }
public static Tuple <int, PropertyInfo>[] GetMembers(Type type) { if (type.GetTypeInfo().GetCustomAttributes(typeof(ZeroFormattableAttribute), true).FirstOrDefault() == null) { throw new InvalidOperationException("Type must be marked with ZeroFormattableAttribute. " + type.Name); } var dict = new Dictionary <int, PropertyInfo>(); foreach (var item in FSharpType.GetRecordFields(type, null)) { if (item.GetCustomAttributes(typeof(IgnoreFormatAttribute), true).Any()) { continue; } var index = item.GetCustomAttributes(typeof(IndexAttribute), true).Cast <IndexAttribute>().FirstOrDefault(); if (index == null) { throw new InvalidOperationException("Public property must be marked with IndexAttribute or IgnoreFormatAttribute. " + type.Name + "." + item.Name); } if (dict.ContainsKey(index.Index)) { throw new InvalidOperationException("IndexAttribute is not allow duplicate number. " + type.Name + "." + item.Name + ", Index:" + index.Index); } dict[index.Index] = item; } return(dict.OrderBy(x => x.Key).Select(x => Tuple.Create(x.Key, x.Value)).ToArray()); }
private Union CreateUnion(Type t) { Union u = new Union(); u.TagReader = (s) => FSharpValue.PreComputeUnionTagReader(t, null).Invoke(s); u.Cases = new List <UnionCase>(); UnionCaseInfo[] cases = FSharpType.GetUnionCases(t, null); foreach (UnionCaseInfo unionCaseInfo in cases) { UnionCase unionCase = new UnionCase(); unionCase.Tag = unionCaseInfo.Tag; unionCase.Name = unionCaseInfo.Name; unionCase.Fields = unionCaseInfo.GetFields(); unionCase.FieldReader = (s) => FSharpValue.PreComputeUnionReader(unionCaseInfo, null).Invoke(s); unionCase.Constructor = (s) => FSharpValue.PreComputeUnionConstructor(unionCaseInfo, null).Invoke(s); u.Cases.Add(unionCase); } return(u); }
private static IType GetTypeArgumentType([NotNull] FSharpType arg, [CanBeNull] IType typeParam, [CanBeNull] IList <ITypeParameter> typeParamsFromContext, [NotNull] IPsiModule psiModule, bool isFromMethodSig) { return(arg.IsGenericParameter ? FindTypeParameterByName(arg, typeParamsFromContext, psiModule) ?? typeParam : GetType(arg, typeParamsFromContext, psiModule, isFromMethodSig)); }
private static IType GetSingleTypeArgument([NotNull] FSharpType fsType, IList <ITypeParameter> typeParamsFromContext, IPsiModule psiModule, bool isFromMethodSig) { Assertion.Assert(fsType.GenericArguments.Count == 1, "fsType.GenericArguments.Count == 1"); return(GetTypeArgumentType(fsType.GenericArguments[0], null, typeParamsFromContext, psiModule, isFromMethodSig) ?? TypeFactory.CreateUnknownType(psiModule)); }
public static bool Test() { FSharpType.IsTuple(typeof(string)); //FSharpType.IsRecord(typeof(string), null); return((bool)typeof(FSharpReflectionExtensions).GetTypeInfo() .GetMethod("FSharpType.IsRecord.Static") .Invoke(null, new object[] { typeof(string), null })); }
static TypeInfo BuildType(Type type) { var ti = type.GetTypeInfo(); // order by key(important for use jump-table of switch) var unionCases = FSharpType.GetUnionCases(type, null).OrderBy(x => x.Tag).ToArray(); var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); TypeBuilder typeBuilder = DynamicAssembly.DefineType("MessagePack.FSharp.Formatters." + SubtractFullNameRegex.Replace(type.FullName, string.Empty).Replace(".", "_") + "Formatter" + +Interlocked.Increment(ref nameSequence), TypeAttributes.Public | TypeAttributes.Sealed, null, new[] { formatterType }); var stringByteKeysFields = new FieldBuilder[unionCases.Length]; // create map dictionary { var method = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); foreach (var unionCase in unionCases) { stringByteKeysFields[unionCase.Tag] = typeBuilder.DefineField("stringByteKeysField" + unionCase.Tag, typeof(byte[][]), FieldAttributes.Private | FieldAttributes.InitOnly); } var il = method.GetILGenerator(); BuildConstructor(type, unionCases, method, stringByteKeysFields, il); } { var method = typeBuilder.DefineMethod( "Serialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, returnType: null, parameterTypes: new Type[] { typeof(MessagePackWriter).MakeByRefType(), type, typeof(MessagePackSerializerOptions) }); method.DefineParameter(1, ParameterAttributes.None, "writer"); method.DefineParameter(2, ParameterAttributes.None, "value"); method.DefineParameter(3, ParameterAttributes.None, "options"); var il = method.GetILGenerator(); BuildSerialize(type, unionCases, method, stringByteKeysFields, il, 1); } { MethodBuilder method = typeBuilder.DefineMethod( "Deserialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, type, new Type[] { refMessagePackReader, typeof(MessagePackSerializerOptions) }); method.DefineParameter(1, ParameterAttributes.None, "reader"); method.DefineParameter(2, ParameterAttributes.None, "options"); var il = method.GetILGenerator(); BuildDeserialize( type, unionCases, method, stringByteKeysFields, il, 1); // firstArgIndex:0 is this. } return(typeBuilder.CreateTypeInfo()); }
private static IType FindTypeParameterByName([NotNull] FSharpType type, [CanBeNull] IEnumerable <ITypeParameter> typeParameters, [NotNull] IPsiModule psiModule) { var typeParam = typeParameters?.FirstOrDefault(p => p.ShortName == type.GenericParameter.DisplayName); return(typeParam != null ? TypeFactory.CreateType(typeParam) : TypeFactory.CreateUnknownType(psiModule)); }
public static IType GetType([NotNull] FSharpType fsType, [NotNull] ITypeMemberDeclaration methodDeclaration, [NotNull] IList <ITypeParameter> methodTypeParams, [NotNull] IPsiModule psiModule, bool isFromReturn) { var typeParametersFromType = GetOuterTypeParameters(methodDeclaration); var typeParamsFromContext = typeParametersFromType.Prepend(methodTypeParams).ToIList(); return(GetType(fsType, typeParamsFromContext, psiModule, true, isFromReturn)); }
public override bool CanConvert(Type objectType) { return(FSharpType.IsUnion(objectType, null) && // It seems that both option and list are implemented using discriminated unions, // so tell json.net to ignore them and use different serializer !(FSharpType.IsRecord(objectType, null)) && !(objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(FSharpList <>)) && !(objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(FSharpOption <>))); }
public IEnumerable <T> EnumerateRows <T>() { var isFsharpRecordType = FSharpType.IsRecord(typeof(T), FSharpOption <BindingFlags> .None); // F# record型の場合とそれ以外とで処理を分岐する. // -> F# recordは引数なしのデフォルトコンストラクタがないため. if (FSharpType.IsRecord(typeof(T), FSharpOption <BindingFlags> .None)) { // コンストラクタの取得 var ctor = BuildConstructor(typeof(T), false); if (!_constructorArgsInfoCache.TryGetValue(typeof(T), out ConstructorArgsInfo[] keys))
public static IType GetType([NotNull] FSharpType fsType, [NotNull] ITypeMemberDeclaration typeMemberDeclaration, [NotNull] IPsiModule psiModule) { try { return(GetType(fsType, GetOuterTypeParameters(typeMemberDeclaration), psiModule)); } catch (ErrorLogger.UnresolvedPathReferenceNoRange) { return(TypeFactory.CreateUnknownType(psiModule)); } }
/// <summary> /// Creates a modified copy of the original object. /// </summary> /// <typeparam name = "T"></typeparam> /// <typeparam name = "TProperty">The type of the property.</typeparam> /// <param name = "record">The record.</param> /// <param name = "property">Name of the property.</param> /// <param name = "value">The value.</param> /// <returns></returns> static T CreateModifiedCopy <T, TProperty>(T record, PropertyInfo property, TProperty value) { var originalValues = FSharpType.GetRecordFields(typeof(T), null) .Select(p => new{ X = p, Y = FSharpValue.GetRecordField(record, p) }); var values = originalValues .Select(t => t.X == property ? value : t.Y) .ToArray(); return((T)FSharpValue.MakeRecord(typeof(T), values, FSharpOption <BindingFlags> .None)); }
private static FSharpType GetStrippedType([NotNull] FSharpType fsType) { try { return(fsType.StrippedType); } catch (Exception e) { Logger.LogMessage(LoggingLevel.WARN, "Error mapping type {0}", fsType); Logger.LogExceptionSilently(e); return(null); } }
public void IsTupleTimed() { object tup = Tupler.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); Timer.Action1 = () => Tupler.IsTuple(tup); Timer.Action2 = () => FSharpType.IsTuple(tup.GetType()); var elapsed = Timer.Go(); Console.WriteLine("Impromptu: " + elapsed.Item1); Console.WriteLine("FSharp Refelection: " + elapsed.Item2); Console.WriteLine("Impromptu VS FSharp Reflection: {0}", TimeIt.RelativeSpeed(elapsed)); Assert.Less(elapsed.Item1, elapsed.Item2); }
private static bool HasGenericTypeParams([NotNull] FSharpType fsType) { if (fsType.IsGenericParameter) { return(true); } foreach (var typeArg in fsType.GenericArguments) { if (typeArg.IsGenericParameter || HasGenericTypeParams(typeArg)) { return(true); } } return(false); }
public static FilterContainer GenerateEqualityFilter <T>(this Expression expression) where T : class { var binaryExpression = expression as BinaryExpression; var value = GetValue(binaryExpression.Right); if (FSharpType.IsUnion(value.GetType(), FSharpOption <BindingFlags> .None)) { var fields = FSharpValue.GetUnionFields(value, value.GetType(), FSharpOption <BindingFlags> .None); var unionCase = fields.Item1; value = unionCase.Name; } var filterDescriptor = new FilterDescriptor <T>(); var fieldName = GetFieldName(binaryExpression.Left); return(filterDescriptor.Term(fieldName, value)); }
public IEnumerable <T> Read <T>() { if (!HasNext) { throw new Exception("The data has already been loaded."); } var isFsharpRecordType = FSharpType.IsRecord(typeof(T), FSharpOption <BindingFlags> .None); // F# record型の場合とそれ以外とで処理を分岐する. // -> F# recordは引数なしのデフォルトコンストラクタがないため. if (FSharpType.IsRecord(typeof(T), FSharpOption <BindingFlags> .None)) { // コンストラクタの取得 var ctor = BuildConstructor(typeof(T), false); if (!_constructorArgsInfoCache.TryGetValue(typeof(T), out ConstructorArgsInfo[] keys))
public static IType GetType([NotNull] FSharpType fsType, [NotNull] ITypeMemberDeclaration methodDeclaration, [NotNull] IList <ITypeParameter> methodTypeParams, [NotNull] IPsiModule psiModule, bool isFromReturn) { var typeParametersFromType = GetOuterTypeParameters(methodDeclaration); var typeParamsFromContext = typeParametersFromType.Prepend(methodTypeParams).ToIList(); try { return(GetType(fsType, typeParamsFromContext, psiModule, true, isFromReturn)); } catch (ErrorLogger.UnresolvedPathReferenceNoRange) { return(TypeFactory.CreateUnknownType(psiModule)); } }
public JsonObjectDescription GetObjectDescription <T>() { var description = Default.GetObjectDescription <T>(); var t = typeof(T); if (FSharpType.IsRecord(t, null)) { var ctor = t.GetConstructors(BindingFlags.Public | BindingFlags.Instance).OrderByDescending(a => a.GetParameters().Length) .FirstOrDefault(); var fields = FSharpType.GetRecordFields(t, null); var members = description.Members.Where(m => fields.Any(f => f.Name == m.MemberName)).ToArray(); description = new JsonObjectDescription(ctor, null, members); } return(description); }
public static object Create <TTypeResolver, T>() where TTypeResolver : ITypeResolver, new() { var t = typeof(T); var ti = t.GetTypeInfo(); if (!FSharpType.IsUnion(t, null)) { throw new InvalidOperationException("Type must be F# Discriminated Union. " + ti.FullName); } var unionCases = FSharpType.GetUnionCases(t, null); var generateTypeInfo = BuildFormatter(typeof(TTypeResolver), t, unionCases); var formatter = Activator.CreateInstance(generateTypeInfo.AsType()); return(formatter); }
static FormatterCache() { if (!FSharpType.IsUnion(typeof(T), null)) { return; } var ti = typeof(T).GetTypeInfo(); var formatterTypeInfo = BuildType(typeof(T)); if (formatterTypeInfo == null) { return; } Formatter = (IMessagePackFormatter <T>)Activator.CreateInstance(formatterTypeInfo.AsType()); }
static TypeInfo BuildType(Type type) { var ti = type.GetTypeInfo(); // order by key(important for use jump-table of switch) var unionCases = FSharpType.GetUnionCases(type, null).OrderBy(x => x.Tag).ToArray(); var formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type); var typeBuilder = assembly.ModuleBuilder.DefineType("MessagePack.FSharp.Formatters." + SubtractFullNameRegex.Replace(type.FullName, "").Replace(".", "_") + "Formatter" + +Interlocked.Increment(ref nameSequence), TypeAttributes.Public | TypeAttributes.Sealed, null, new[] { formatterType }); var stringByteKeysFields = new FieldBuilder[unionCases.Length]; // create map dictionary { var method = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); foreach (var unionCase in unionCases) { stringByteKeysFields[unionCase.Tag] = typeBuilder.DefineField("stringByteKeysField" + unionCase.Tag, typeof(byte[][]), FieldAttributes.Private | FieldAttributes.InitOnly); } var il = method.GetILGenerator(); BuildConstructor(type, unionCases, method, stringByteKeysFields, il); } { var method = typeBuilder.DefineMethod("Serialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, typeof(int), new Type[] { typeof(byte[]).MakeByRefType(), typeof(int), type, typeof(IFormatterResolver) }); var il = method.GetILGenerator(); BuildSerialize(type, unionCases, method, stringByteKeysFields, il); } { var method = typeBuilder.DefineMethod("Deserialize", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual, type, new Type[] { typeof(byte[]), typeof(int), typeof(IFormatterResolver), typeof(int).MakeByRefType() }); var il = method.GetILGenerator(); BuildDeserialize(type, unionCases, method, stringByteKeysFields, il); } return(typeBuilder.CreateTypeInfo()); }
public static object Create <TTypeResolver, T>() where TTypeResolver : ITypeResolver, new() { var resolverType = typeof(TTypeResolver); var t = typeof(T); if (!FSharpType.IsRecord(t, null)) { throw new InvalidOperationException("Type must be F# record. " + t.Name); } var elementType = t; var members = GetMembers(elementType); var length = ValidateAndCalculateLength(resolverType, elementType, members); var generateTypeInfo = BuildFormatter(DynamicAssemblyHolder.Module, resolverType, elementType, length, members); var formatter = Activator.CreateInstance(generateTypeInfo.AsType()); return(formatter); }
public void ListToTupleTimed() { var list = new object[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; Timer.Action1 = () => Tupler.ToTuple(list); Timer.Action2 = () => { var types = list.Select(it => it.GetType()).ToArray(); var tupType = FSharpType.MakeTupleType(types); FSharpValue.MakeTuple(list, tupType); }; var elapsed = Timer.Go(50000); Console.WriteLine("Impromptu: " + elapsed.Item1); Console.WriteLine("FSharp Refelection: " + elapsed.Item2); Console.WriteLine("Impromptu VS FSharp Reflection: {0}", TimeIt.RelativeSpeed(elapsed)); Assert.Less(elapsed.Item1, elapsed.Item2); }
public IJsonFormatter GetFormatter(Type t) { var ti = t.GetTypeInfo(); var resolverType = typeof(FSharpResolver <TSymbol, TResolver>); if (FSharpType.IsRecord(t, null)) { Type formatterType; if (ti.IsValueType) { formatterType = typeof(ComplexStructFormatter <, ,>); } else { formatterType = typeof(ComplexClassFormatter <, ,>); } return(CreateInstance(formatterType, new Type[] { t, typeof(TSymbol), resolverType })); } else if (ti.IsFSharpMap()) { return(CreateInstance(typeof(FSharpMapFormatter <, ,>), new [] { ti.GenericTypeArguments[1], typeof(TSymbol), resolverType })); } else if (ti.IsFSharpList()) { return(CreateInstance(typeof(FSharpListFormatter <, ,>), new Type[] { ti.GenericTypeArguments[0], typeof(TSymbol), resolverType })); } else if (ti.IsFSharpOption()) { return(CreateInstance(typeof(FSharpOptionFormatter <, ,>), new[] { ti.GenericTypeArguments[0], typeof(TSymbol), resolverType })); } else if (ti.IsFSharpValueOption()) { return(CreateInstance(typeof(FSharpValueOptionFormatter <, ,>), new[] { ti.GenericTypeArguments[0], typeof(TSymbol), resolverType })); } return(Default.GetFormatter(t)); }
protected IType GetType([CanBeNull] FSharpType fsType) => fsType != null ? fsType.MapType(AllTypeParameters, Module) : TypeFactory.CreateUnknownType(Module);
public static void Test() { FSharpType.IsTuple(typeof(string)); FSharpType.IsRecord(typeof(string), null); }
/// <summary> /// Type情報からデフォルトのインスタンスを生成する. /// </summary> /// <param name="type">デフォルトインスタンスを生成したいType情報</param> /// <returns>Type情報から生成したインスタンス</returns> public static object MakeDefault(this Type type) { var none = FSharpOption <BindingFlags> .None; if (type == typeof(int)) { return(default(int)); } if (type == typeof(uint)) { return(default(uint)); } if (type == typeof(short)) { return(default(short)); } if (type == typeof(ushort)) { return(default(ushort)); } if (type == typeof(long)) { return(default(long)); } if (type == typeof(ulong)) { return(default(ulong)); } if (type == typeof(byte)) { return(default(byte)); } if (type == typeof(sbyte)) { return(default(sbyte)); } if (type == typeof(bool)) { return(default(bool)); } if (type == typeof(float)) { return(default(float)); } if (type == typeof(double)) { return(default(double)); } if (type == typeof(decimal)) { return(default(decimal)); } if (type == typeof(char)) { return(default(char)); } if (type == typeof(string)) { return(default(string)); } if (type == typeof(Guid)) { return(default(Guid)); } if (type == typeof(DateTime)) { return(default(DateTime)); } if (type == typeof(DateTimeOffset)) { return(default(DateTimeOffset)); } if (type == typeof(byte[])) { return(default(byte[])); } if (type == typeof(int?)) { return(default(int?)); } if (type == typeof(uint?)) { return(default(uint?)); } if (type == typeof(short?)) { return(default(short?)); } if (type == typeof(ushort?)) { return(default(ushort?)); } if (type == typeof(long?)) { return(default(long?)); } if (type == typeof(ulong?)) { return(default(ulong?)); } if (type == typeof(byte?)) { return(default(byte?)); } if (type == typeof(sbyte?)) { return(default(sbyte?)); } if (type == typeof(bool?)) { return(default(bool?)); } if (type == typeof(float?)) { return(default(float?)); } if (type == typeof(double?)) { return(default(double?)); } if (type == typeof(decimal?)) { return(default(decimal?)); } if (type == typeof(char?)) { return(default(char?)); } if (type == typeof(Guid?)) { return(default(Guid?)); } if (type == typeof(DateTime?)) { return(default(DateTime?)); } if (type == typeof(DateTimeOffset?)) { return(default(DateTimeOffset?)); } if (type == typeof(FSharpOption <int>)) { return(FSharpOption <int> .None); } if (type == typeof(FSharpOption <uint>)) { return(FSharpOption <uint> .None); } if (type == typeof(FSharpOption <short>)) { return(FSharpOption <short> .None); } if (type == typeof(FSharpOption <ushort>)) { return(FSharpOption <ushort> .None); } if (type == typeof(FSharpOption <long>)) { return(FSharpOption <long> .None); } if (type == typeof(FSharpOption <ulong>)) { return(FSharpOption <ulong> .None); } if (type == typeof(FSharpOption <byte>)) { return(FSharpOption <byte> .None); } if (type == typeof(FSharpOption <sbyte>)) { return(FSharpOption <sbyte> .None); } if (type == typeof(FSharpOption <bool>)) { return(FSharpOption <bool> .None); } if (type == typeof(FSharpOption <float>)) { return(FSharpOption <float> .None); } if (type == typeof(FSharpOption <double>)) { return(FSharpOption <double> .None); } if (type == typeof(FSharpOption <decimal>)) { return(FSharpOption <decimal> .None); } if (type == typeof(FSharpOption <char>)) { return(FSharpOption <char> .None); } if (type == typeof(FSharpOption <string>)) { return(FSharpOption <string> .None); } if (type == typeof(FSharpOption <Guid>)) { return(FSharpOption <Guid> .None); } if (type == typeof(FSharpOption <DateTime>)) { return(FSharpOption <DateTime> .None); } if (type == typeof(FSharpOption <DateTimeOffset>)) { return(FSharpOption <DateTimeOffset> .None); } if (type == typeof(FSharpOption <byte[]>)) { return(FSharpOption <byte[]> .None); } // Option型(F#) // - FSharpType.IsUnion()でも引っ掛かってしまうので、 // それよりも前に判定をする必要がある. if (type.IsFsharpOption()) { return(type .GetProperty("None", BindingFlags.Public | BindingFlags.Static) .GetGetMethod() .Invoke(null, null)); } // 判別共用体(F#) if (type.IsFsharpDiscriminatedUnions()) { var ctor = FSharpType.GetUnionCases(type, none).FirstOrDefault(); if (ctor == null) { throw new Exception("Invalid discriminated-unions."); } var ps = ctor.GetFields(); var qs = new object[ps.Length]; for (var i = 0; i < ps.Length; i++) { qs[i] = ps[i].PropertyType.MakeDefault(); } return(FSharpValue.MakeUnion(ctor, qs, none)); } // 列挙型 if (type.IsEnum) { return(type.GetEnumValue(0)); } // 構造体 if (type.IsValueType) { return(Activator.CreateInstance(type)); } // クラス if (type.IsClass) { var ctor = type.GetConstructors().FirstOrDefault(); // publicコンストラクタが存在しない場合、nullを返す if (ctor is null) { return(null); } else { var ps = ctor.GetParameters(); var qs = new object[ps.Length]; for (int i = 0; i < ps.Length; i++) { qs[i] = ps[i].ParameterType.MakeDefault(); } #if NET40 || NET45 || NET46 || NET472 || NET48 || NETCOREAPP3_1 || NET5_0 return(type.Constructor(qs)); #else return(Activator.CreateInstance(type, qs)); #endif } } throw new ArgumentException("'type' is not supported."); }