【问题标题】:how to get the default value of a type if the type is only known as System.Type? [duplicate]如果类型仅称为 System.Type,如何获取类型的默认值? [复制]
【发布时间】:2010-11-19 20:25:29
【问题描述】:

如果我想要一个返回给定类型的默认值的方法并且该方法是通用的,我可以返回一个默认值,如下所示:

public static T GetDefaultValue()
{
  return default(T);
}

如果我的类型仅作为 System.Type 对象,我可以做类似的事情吗?

public static object GetDefaultValue(Type type)
{
  //???
}

【问题讨论】:

    标签: c# generics default


    【解决方案1】:

    因为你真的只需要担心值类型(引用类型只是空),你可以使用Activator.CreateInstance 来调用它们的默认构造函数。

    public static object GetDefaultValue(Type type) {
       return type.IsValueType ? Activator.CreateInstance(type) : null;
    }
    

    编辑:乔恩(当然)是正确的。 IsClass 不够详尽 - 如果 type 是一个接口,它会返回 False

    【讨论】:

    • 最好使用!type.IsValueType,来应对接口。
    • 改进答案的建议:将this添加到参数中,使其成为扩展方法。
    • 在 dotnet core 2 中似乎有一个名为 Type.GetDefaultValue() 的新方法,但它没有出现在任何 MSDN 文档中。
    • 另请注意,这实际上有一个边缘情况:github.com/dotnet/corefx/issues/31646#issuecomment-411443507 如果结构有默认构造函数,它将运行该构造函数。 System.Runtime.Serialization.FormatterServices.GetUninitializedObject 其实更准确。
    【解决方案2】:

    这是我通常的做法。这避免了整个 'IsValueType' 或完全搜索构造函数的问题。

    public static object MakeDefault(this Type type)
    {
        var makeDefault = typeof(ExtReflection).GetMethod("MakeDefaultGeneric");
        var typed = makeDefault.MakeGenericMethod(type);
        return typed.Invoke(null, new object[] { });
    }
    
    public static T MakeDefaultGeneric<T>()
    {
        return default(T);
    }
    

    【讨论】:

    • 你能解释一下这与 Mark Brackett 的答案有何不同/更好/更差吗?
    • 我不能说它是好是坏;我想取决于你的需要。如果没有任何缓存,我的回答几乎肯定会变慢。我特别喜欢这个解决方案的一件事是,它确实使用了我们试图模拟的内置语言功能;而不是模拟它。
    【解决方案3】:

    没有泛型,你不能保证这个类型有一个无参数的构造函数,但是你可以使用反射来搜索:

    public static object GetDefaultValue(Type type)
    {
        ConstructorInfo ci = type.GetConstructor( new Type[] {} );
        return ci.Invoke( new object[] {} );
    }
    

    我在一个控制台应用程序中尝试过这个,它返回一个类的“默认”实例——假设它是一个类。如果您还需要它来处理引用类型,则需要一种额外的技术。

    【讨论】:

    • 引用类型的默认值为 null,而不是类的实例。因此,如果他按照您的建议进行操作,GetDefault(T) 将返回 null,而 GetDefault(Type) 将在可能的情况下尝试创建一个实例,这是错误的。你的技术不是没用的,但我想它更像是“T GetInstance(T) where T : new() {return new T();}”类型的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 2011-02-14
    • 1970-01-01
    • 2010-09-15
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多