0

这两种说法是一样的吗?

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


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

我只想在它有值时设置生日,但我想在 1 行中进行。

4

2 回答 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"));
于 2019-12-24T22:22:34.207 回答
1

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

其次,将很多东西放在一条线上的唯一代价是:

  • 好久不见
  • 要花很多时间才能理解它
  • 不知何故,尝试调试它的时间更糟

第一个有 6(六)个位置,其中一个是空引用异常可能会命中。也是演员和反思。这是一个异常的滋生地。从现在起 6 个月后必须调试该线路的任何人都会从中得到噩梦。那可以是你。

代码可读性和可调试性应该是第一位的。尝试将其限制为 1 个操作/代码行,将其结果分配给临时变量,以获得有用的异常。永远不要担心临时变量对性能的影响。在编译器、JiT 编译器和死代码检测之间,无论如何这些都将在发布版本中被删除。

于 2019-12-24T21:46:30.323 回答