c#合并与设置为null时的if语句相同吗?

问题描述 投票:0回答:2

这两个语句是否相同?

if (dep.BirthDate.HasValue) {
  myObj.GetType().GetProperty("birthdate").SetValue(myObj, (DateTime)dep.BirthDate, null);
}


myObj.GetType().GetProperty("birthdate").SetValue(myObj, dep.BirthDate ?? null, null);

我只想在它具有值的情况下设置生日,但是我想在一行中进行设置。

c# null nullable gettype null-coalescing
2个回答
2
投票

正如@IanKemp所建议的,当您要跳过属性分配时,无法避免if-check。不要与分配默认值混淆。

最简单的解决方案是将可空值检查和属性分配封装到单个操作中。为了避免传递PropertyInfo,可以使用扩展方法:

public static class ReflectionExtensions
{
    public static void SetValueIfNotNull<T>(this PropertyInfo prop, object obj, T? maybe)
        where T : struct
    {
        if (maybe.HasValue)
            prop.SetValue(obj, maybe.Value);
    }
}

用法:

myObj.GetType().GetProperty("birthdate").SetValueIfNotNull(myObj, dep.BirthDate);

或者如果您只需要使用可为空的值并且属性设置不是很多事情,那么您可以编写一个可为空的扩展名,它将代码带回到不可为空的路径:

public static class NullableExtensions
{
    // Note that action has non-nullable argument
    public static void Invoke<T>(this Nullable<T> nullable, Action<T> action)
        where T: struct
    {
        if (nullable.HasValue)
            action(nullable.Value);
    }
}

这种方法可以交换东西-现在,如果nullable具有值,则可以对nullable变量的值调用操作:

dep.BirthDate.Invoke(date => myObj.GetType().GetProperty("birthday").SetValue(myObj, date));

或者如果您要调用单参数函数,也可以这样

dep.BirthDate.Invoke(myObj.SetProperty<DateTime>("birthday"));

1
投票

首先,这听起来像是一个速度问题。因此,速度咆哮:https://ericlippert.com/2012/12/17/performance-rant/

第二,将很多东西放入一行的唯一价格是:

  • 花一点时间阅读它
  • 花一点时间了解它
  • 以某种方式[尝试对其进行调试
第一个有6(六)个地方,可能会遇到null引用异常中的任何一个。也是一种投射和反思。这是一个例外的温床。谁将从现在开始的6个月内调试那条线,谁就会从中噩梦。那可以是你。

代码可读性和可调试性应该放在第一位。尝试将其限制为1个操作/代码行,并将其结果分配给一个临时变量,以获取有用的Exceptions。永远不必担心临时变量对性能的影响。在编译器,JiT编译器和死代码检测之间,无论如何都会适当地在发行版本中删除它们。

© www.soinside.com 2019 - 2024. All rights reserved.