C# default(Type) 的编程等效项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/325426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatic equivalent of default(Type)
提问by tags2k
I'm using reflection to loop through a Type's properties and set certain types to their default. Now, I could do a switch on the type and set the default(Type)explicitly, but I'd rather do it in one line. Is there a programmatic equivalent of default?
我正在使用反射来遍历 aType的属性并将某些类型设置为其默认值。现在,我可以在类型上进行切换并default(Type)明确设置,但我宁愿在一行中进行。是否有默认的编程等价物?
采纳答案by Dror Helper
- In case of a value type use Activator.CreateInstanceand it should work fine.
- When using reference type just return null
- 如果是值类型,请使用Activator.CreateInstance,它应该可以正常工作。
- 使用引用类型时只返回 null
public static object GetDefault(Type type)
{
if(type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
In the newer version of .net such as .net standard, type.IsValueTypeneeds to be written as type.GetTypeInfo().IsValueType
在.net标准等较新版本的.net中,type.IsValueType需要写成type.GetTypeInfo().IsValueType
回答by Vilx-
Can't find anything simple and elegant just yet, but I have one idea: If you know the type of the property you wish to set, you can write your own default(T). There are two cases - Tis a value type, and Tis a reference type. You can see this by checking T.IsValueType. If Tis a reference type, then you can simply set it to null. If Tis a value type, then it will have a default parameterless constructor that you can call to get a "blank" value.
暂时还找不到任何简单优雅的东西,但我有一个想法:如果您知道要设置的属性类型,则可以编写自己的default(T). 有两种情况——T是值类型,T是引用类型。您可以通过检查看到这一点T.IsValueType。如果T是引用类型,那么您可以简单地将其设置为null. 如果T是值类型,那么它将有一个默认的无参数构造函数,您可以调用它来获取“空白”值。
回答by kpollock
I do the same task like this.
我做同样的任务。
//in MessageHeader
private void SetValuesDefault()
{
MessageHeader header = this;
Framework.ObjectPropertyHelper.SetPropertiesToDefault<MessageHeader>(this);
}
//in ObjectPropertyHelper
public static void SetPropertiesToDefault<T>(T obj)
{
Type objectType = typeof(T);
System.Reflection.PropertyInfo [] props = objectType.GetProperties();
foreach (System.Reflection.PropertyInfo property in props)
{
if (property.CanWrite)
{
string propertyName = property.Name;
Type propertyType = property.PropertyType;
object value = TypeHelper.DefaultForType(propertyType);
property.SetValue(obj, value, null);
}
}
}
//in TypeHelper
public static object DefaultForType(Type targetType)
{
return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
}
回答by BSick7
The chosen answer is a good answer, but be careful with the object returned.
选择的答案是一个很好的答案,但要小心返回的对象。
string test = null;
string test2 = "";
if (test is string)
Console.WriteLine("This will never be hit.");
if (test2 is string)
Console.WriteLine("Always hit.");
Extrapolating...
推断...
string test = GetDefault(typeof(string));
if (test is string)
Console.WriteLine("This will never be hit.");
回答by Rob Fonseca-Ensor
Why do you say generics are out of the picture?
你为什么说泛型不在图片中?
public static object GetDefault(Type t)
{
Func<object> f = GetDefault<object>;
return f.Method.GetGenericMethodDefinition().MakeGenericMethod(t).Invoke(null, null);
}
private static T GetDefault<T>()
{
return default(T);
}
回答by drake7707
Why not call the method that returns default(T) with reflection ? You can use GetDefault of any type with:
为什么不使用反射调用返回 default(T) 的方法?您可以将任何类型的 GetDefault 用于:
public object GetDefault(Type t)
{
return this.GetType().GetMethod("GetDefaultGeneric").MakeGenericMethod(t).Invoke(this, null);
}
public T GetDefaultGeneric<T>()
{
return default(T);
}
回答by Konstantin Isaev
The Expressions can help here:
表达式可以在这里提供帮助:
private static Dictionary<Type, Delegate> lambdasMap = new Dictionary<Type, Delegate>();
private object GetTypedNull(Type type)
{
Delegate func;
if (!lambdasMap.TryGetValue(type, out func))
{
var body = Expression.Default(type);
var lambda = Expression.Lambda(body);
func = lambda.Compile();
lambdasMap[type] = func;
}
return func.DynamicInvoke();
}
I did not test this snippet, but i think it should produce "typed" nulls for reference types..
我没有测试这个片段,但我认为它应该为引用类型产生“类型化”的空值..
回答by JoelFan
You can use PropertyInfo.SetValue(obj, null). If called on a value type it will give you the default. This behavior is documented in .NET 4.0and in .NET 4.5.
您可以使用PropertyInfo.SetValue(obj, null). 如果在值类型上调用,它将为您提供默认值。此行为记录在 .NET 4.0和.NET 4.5 中。
回答by Paul Fleming
Equivalent to Dror's answer but as an extension method:
相当于 Dror 的答案,但作为扩展方法:
namespace System
{
public static class TypeExtensions
{
public static object Default(this Type type)
{
object output = null;
if (type.IsValueType)
{
output = Activator.CreateInstance(type);
}
return output;
}
}
}
回答by casperOne
If you're using .NET 4.0 or above and you want a programmatic version that isn't a codification of rules defined outside of code, you can create an Expression, compile and run it on-the-fly.
如果您使用的是 .NET 4.0 或更高版本,并且您想要一个不是代码之外定义的规则的编纂的编程版本,您可以创建一个Expression,即时编译和运行它。
The following extension method will take a Typeand get the value returned from default(T)through the Defaultmethodon the Expressionclass:
以下扩展方法将采用 aType并default(T)通过类上的Default方法获取返回的值Expression:
public static T GetDefaultValue<T>()
{
// We want an Func<T> which returns the default.
// Create that expression here.
Expression<Func<T>> e = Expression.Lambda<Func<T>>(
// The default value, always get what the *code* tells us.
Expression.Default(typeof(T))
);
// Compile and return the value.
return e.Compile()();
}
public static object GetDefaultValue(this Type type)
{
// Validate parameters.
if (type == null) throw new ArgumentNullException("type");
// We want an Func<object> which returns the default.
// Create that expression here.
Expression<Func<object>> e = Expression.Lambda<Func<object>>(
// Have to convert to object.
Expression.Convert(
// The default value, always get what the *code* tells us.
Expression.Default(type), typeof(object)
)
);
// Compile and return the value.
return e.Compile()();
}
You should also cache the above value based on the Type, but be aware if you're calling this for a large number of Typeinstances, and don't use it constantly, the memory consumed by the cache might outweigh the benefits.
您还应该根据 缓存上述值Type,但请注意,如果您为大量Type实例调用它,并且不要经常使用它,缓存消耗的内存可能会超过好处。

