我正在使用反射来遍历Type的属性并将某些类型设置为其默认值。 现在,我可以对类型进行切换并显式设置default(Type) ,但我宁愿一行执行。 是否有程序等效的默认值?


#1楼

您可以使用PropertyInfo.SetValue(obj, null) 。 如果调用一个值类型,它将为您提供默认值。 .NET 4.0和.NET 4.5中记录了此行为。


#2楼

等同于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;}}
}

#3楼

如果您使用的是.NET 4.0或更高版本,并且想要的程序版本不是在代码外部定义的规则的编纂,则可以创建一个Expression ,并即时对其进行编译和运行。

以下扩展方法将采用Type并通过Expression类的Default方法获取从default(T)返回的Default

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()();
}

您还应该基于Type缓存上述值,但是要知道,如果您是针对大量的Type实例调用此值的,并且不要一直使用它,则缓存消耗的内存可能会超过收益。


#4楼

这是优化的Flem解决方案:

using System.Collections.Concurrent;namespace System
{public static class TypeExtension{//a thread-safe way to hold default instances created at run-timeprivate 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;}}
}

#5楼

 /// <summary>/// returns the default value of a specified type/// </summary>/// <param name="type"></param>public static object GetDefault(this Type type){return type.IsValueType ? (!type.IsGenericType ? Activator.CreateInstance(type) : type.GenericTypeArguments[0].GetDefault() ) : null;}

#6楼

暂时还找不到简单而优雅的东西,但是我有一个主意:如果您知道要设置的属性的类型,则可以编写自己的default(T) 。 有两种情况T是值类型,而T是引用类型。 您可以通过检查T.IsValueType看到此T.IsValueType 。 如果T是引用类型,则只需将其设置为null 。 如果T是值类型,则它将具有默认的无参数构造函数,您可以调用该构造函数获取“空白”值。


#7楼

我做同样的任务。

//in MessageHeader private void SetValuesDefault(){MessageHeader header = this;             Framework.ObjectPropertyHelper.SetPropertiesToDefault<MessageHeader>(this);}//in ObjectPropertyHelperpublic 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 TypeHelperpublic static object DefaultForType(Type targetType){return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;}

#8楼

  • 如果是值类型,请使用Activator.CreateInstance ,它应该可以正常工作。
  • 使用引用类型时,只需返回null
public static object GetDefault(Type type)
{if(type.IsValueType){return Activator.CreateInstance(type);}return null;
}

在较新的.net版本(例如.net标准)中, type.IsValueType需要写为type.GetTypeInfo().IsValueType


#9楼

选择的答案是一个很好的答案,但是要小心返回的对象。

string test = null;
string test2 = "";
if (test is string)Console.WriteLine("This will never be hit.");
if (test2 is string)Console.WriteLine("Always hit.");

外推...

string test = GetDefault(typeof(string));
if (test is string)Console.WriteLine("This will never be hit.");

#10楼

为什么您说泛型不适合?

    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);}

#11楼

对@Rob Fonseca-Ensor解决方案的调整:由于我使用GetRuntimeMethod而不是GetMethod,因此以下扩展方法也适用于.Net Standard。

public static class TypeExtensions
{public static object GetDefault(this Type t){var defaultValue = typeof(TypeExtensions).GetRuntimeMethod(nameof(GetDefaultGeneric), new Type[] { }).MakeGenericMethod(t).Invoke(null, null);return defaultValue;}public static T GetDefaultGeneric<T>(){return default(T);}
}

...以及针对那些关心质量的人员的相应单元测试:

[Fact]
public void GetDefaultTest()
{// Arrangevar type = typeof(DateTime);// Actvar defaultValue = type.GetDefault();// AssertdefaultValue.Should().Be(default(DateTime));
}

#12楼

为什么不通过反射调用返回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);}

#13楼

表达式可以在这里提供帮助:

    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();}

我没有测试此代码段,但我认为它应该为引用类型生成“类型化”的null。

默认的程序化等效项(类型)相关推荐

  1. 教程|监控项类型—SNMP客户端

    概 述 您可能希望在打印机.网络交换机.路由器或UPS等设备上使用SNMP监控,这些设备通常启用SNMP,在这些设备上尝试设置完整的操作系统和Zabbix代理是不切实际的. 为了能够监控SNMP代理在 ...

  2. LINQ的Java等效项是什么? [关闭]

    LINQ的Java等效项是什么? #1楼 听起来每个人都在谈论的Linq只是LinqToObjects. 我认为,这些功能仅提供了Java现在已经可以完成的功能,但是语法却非常丑陋. 我看到的.net ...

  3. json mysql 字段 默认值_MySQL新增JSON类型字段的使用总结

    最近刚好用到了MySQL的JSON函数做了一些数据处理相关的工作,顺便记录总结一下相关知识点和用法. MySQL从5.7.8开始支持原生JSON数据类型,以JSON类型存储json格式的数据,比字符串 ...

  4. 【笔记】python的传递实参:位置实参、关键字实参、默认值、等效的函数调用、避免实参错误

    文章目录 一.传递实参 1.位置实参 2.关键字实参 3.默认值 4.等效的函数调用 5.避免实参错误 一.传递实参 函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参.向函数传递实参的方式 ...

  5. Abp项目更改默认主题在Blazorl项目的UI上

    Abp项目更改默认主题在Blazorl项目的UI上 参考:Replace Basic Bootstrap theme with a free custom Bootstrap theme https: ...

  6. VS2019 error  : 无法加载具有重复项目项的项目: ....作为 Image 且作为 Image 项类型包括在其中。

    拷贝过来的一个vcc solution,打开时无法加载其中的项目,报错内容如下, error  : 无法加载具有重复项目项的项目: res\POLYGON.png 作为 Image 且作为 Image ...

  7. easyui的combobox设置下拉框默认选中某一项

    JSP页面:可以这样写,提供option的选项, <input class="easyui-combobox" name="customerStatus" ...

  8. springmvc中处理器(控制器)能够返回的类型及处理器默认能够接受的参数类型

    一.处理器(控制器)能够返回的类型: 1.ModelAndView:把数据模型和试图设置到ModelAndView对象中 2.void:把数据类型和视图设置到request域中 3.String:返回 ...

  9. sql limit 子句_Java 8流中的常见SQL子句及其等效项

    sql limit 子句 功能编程允许使用通用语言进行准声明性编程 . 通过使用功能强大的流畅API(例如Java 8的Stream API )或jOOλ的顺序Stream扩展Seq或更复杂的库(例如 ...

最新文章

  1. 配置Activiti Explorer使用MYSQL
  2. LeetCode实战:寻找两个有序数组的中位数
  3. 阿里云凌晨大规模宕机,华北部分网站陷入瘫痪
  4. 强化学习笔记2:序列决策(Sequential Decision Making)过程
  5. Spring Boot WebMagic 入库时 mapper注入提示空指针,以及正确的操作
  6. loadrunner 场景设计-负载生成器管理
  7. java中保留小数位_Java中保留两位小数的方法
  8. 在服务器群集节点安装DHCP服务
  9. win11升级不满足最低系统要求怎么办 windows11升级不满足最低系统要求的解决方法
  10. 2010年5月18日 小细节大隐患
  11. 牛逼!Java 从入门到精通,超全汇总版
  12. 奥维互动地图APP不能用了怎么办?有没有什么替代软件?
  13. android 混淆 minifyEnabled
  14. 小米android6.01 root,小米手机6详细刷成开发版开启root超级权限的教程
  15. Denoise-----去除噪声
  16. ſ xf(sinx)dx 中的f(sinx)到底是什么
  17. google计费接入,Billing结算库支付
  18. 计算机无法进入bios模式,win7进入bios设置界面_win7无法进入bios设置解决办法
  19. java学习之LinkedList(链表)
  20. js中eq neq gt gte lt lte分别是什么意思,如何应用

热门文章

  1. 关于BeginPaint和WM_ERASEBKGND
  2. java 1.7 新io 实践 NIO2
  3. python3爬虫小型代码_python3简单爬虫实现代码
  4. linux read函数_Linux中shell输入ls命令后会系统会发生什么
  5. 配置Yarn-Resourcemanager HA
  6. Linux虚拟文件系统解析
  7. list类型的应用场景 —— Redis实战经验
  8. 微信公众号自定义菜单跳转小程序
  9. 阿里云rds linux平台使用wget 工具下载备份与日志文件
  10. 论文阅读(Xiang Bai——【arXiv2016】Scene Text Detection via Holistic, Multi-Channel Prediction)...