Example #1
0
        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);
        }
Example #2
0
        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));
 }
Example #7
0
 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));
        }
Example #11
0
 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));
     }
 }
Example #14
0
        /// <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);
     }
 }
Example #16
0
        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);
        }
Example #18
0
        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));
        }
Example #19
0
        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));
            }
        }
Example #21
0
        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);
        }
Example #22
0
        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());
            }
Example #24
0
        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);
        }
Example #26
0
        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);
        }
Example #27
0
        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);
Example #29
0
 public static void Test()
 {
     FSharpType.IsTuple(typeof(string));
     FSharpType.IsRecord(typeof(string), null);
 }
Example #30
0
        /// <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.");
        }