Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果类型仅为System.type,如何获取该类型的默认值?_C#_Generics_Default - Fatal编程技术网

C# 如果类型仅为System.type,如何获取该类型的默认值?

C# 如果类型仅为System.type,如何获取该类型的默认值?,c#,generics,default,C#,Generics,Default,如果我想要一个返回给定类型的默认值的方法,并且该方法是泛型的,我可以像这样返回默认值: public static T GetDefaultValue() { return default(T); } 如果该类型仅作为System.type对象,是否可以执行类似操作 public static object GetDefaultValue(Type type) { //??? } 如果没有泛型,则无法保证该类型具有无参数构造函数,但可以使用反射搜索一个: public static

如果我想要一个返回给定类型的默认值的方法,并且该方法是泛型的,我可以像这样返回默认值:

public static T GetDefaultValue()
{
  return default(T);
}
如果该类型仅作为
System.type
对象,是否可以执行类似操作

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

如果没有泛型,则无法保证该类型具有无参数构造函数,但可以使用反射搜索一个:

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

我在一个控制台应用程序中尝试了这一点,它返回了该类的一个“默认”实例——假设它是一个类。如果您需要它也适用于引用类型,那么您将需要一种额外的技术。

因为您实际上只需要担心值类型(引用类型将为null),您可以使用
Activator.CreateInstance
调用它们的默认构造函数

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

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

以下是我通常的操作方式。这避免了整个“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);
}
publicstaticobjectmakedefault(此类型)
{
var makeDefault=typeof(ExtReflection).GetMethod(“MakeDefaultGeneric”);
var typed=makeDefault.MakeGenericMethod(类型);
返回typed.Invoke(null,新对象[]{});
}
公共静态T MakeDefaultGeneric()
{
返回默认值(T);
}

引用类型的默认值为null,不是类的实例。所以,如果他按照您的建议执行,GetDefault(T)将返回null,而GetDefault(Type)将尽可能尝试创建一个实例,这是错误的。您的技术并不是无用的,但我想它更像是“T GetInstance(T)where T:new(){return new T();}”类型的方法。我明白您的意思。谢谢你的更正!你的答案很有用。最好用!type.IsValueType,用于处理接口。改进答案的建议:将
this
添加到参数中,使其成为一个扩展方法。在dotnet core 2中似乎有一个名为
type.GetDefaultValue()
的新方法,但它没有出现在任何MSDN文档中。还要注意,这实际上有一个边缘情况:如果结构有一个默认构造函数,它将运行该构造函数
System.Runtime.Serialization.FormatterServices.GetUninitializedObject
实际上更准确。你能解释一下这与Mark Brackett的答案有什么不同/更好/更差吗?我不能说是更好还是更差;我想这取决于你的需要。如果没有任何缓存,我的回答几乎肯定会更慢。我特别喜欢这个解决方案的一点是,它确实使用了我们试图模仿的内置语言特性;而不是模拟它。