我使用反射来循环一个类型的属性,并将某些类型设置为默认值。现在,我可以在类型上进行切换,并显式地设置默认(type),但我宁愿在一行中完成。在编程中是否存在与默认设置相同的功能?
当前回答
如果是值类型,请使用Activator。CreateInstance,它应该可以正常工作。 当使用引用类型时,只返回null
public static object GetDefault(Type type)
{
if(type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
在。net的新版本,如。net标准中,键入。IsValueType需要被写成type.GetTypeInfo().IsValueType
其他回答
下面的表达可以帮助你:
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();
}
我没有测试这个片段,但我认为它应该为引用类型产生“类型化”空值。
您可以使用PropertyInfo。SetValue (obj, null)。如果在一个值类型上调用,它将为您提供默认值。这种行为在。net 4.0和。net 4.5中都有记录。
这是优化后的Flem方案:
using System.Collections.Concurrent;
namespace System
{
public static class TypeExtension
{
//a thread-safe way to hold default instances created at run-time
private static ConcurrentDictionary<Type, object> typeDefaults =
new ConcurrentDictionary<Type, object>();
public static object GetDefaultValue(this Type type)
{
return type.IsValueType
? typeDefaults.GetOrAdd(type, Activator.CreateInstance)
: null;
}
}
}
为什么你说泛型被淘汰了?
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);
}
我像这样做同样的任务。
//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;
}
推荐文章
- .NET中的Map和Reduce
- 我如何能使一个组合框不可编辑的。net ?
- .NET反射的成本有多高?
- 实体框架回滚并移除不良迁移
- 将流转换为字符串并返回
- 在c#中检查字符串是否只包含数字的最快方法
- IEquatable和重写Object.Equals()之间的区别是什么?
- 创建一个堆栈大小为默认值50倍的线程有什么危险?
- 转换JSON字符串到JSON对象c#
- 显示两个datetime值之间的小时差值
- 如何设置enum为空
- 选择Enum类型的默认值而无需更改值
- 我如何设置在一个组合框中选择的项目,以匹配我的字符串使用c# ?
- String与StringBuilder
- 如何在ASP中使用ILogger进行单元测试。网络核心