c# - 读取对象子属性的优雅方式

标签 c# .net properties logic

假设您正在尝试读取此属性

var town = Staff.HomeAddress.Postcode.Town;

链上的某处可能存在空值。 阅读 Town 的最佳方式是什么?

我一直在试验几种扩展方法...

public static T2 IfNotNull<T1, T2>(this T1 t, Func<T1, T2> fn) where T1 : class
{
    return t != null ? fn(t) : default(T2);
}

var town = staff.HomeAddress.IfNotNull(x => x.Postcode.IfNotNull(y=> y.Town));

public static T2 TryGet<T1, T2>(this T1 t, Func<T1, T2> fn) where T1 : class
{
if (t != null)
{
    try
    {
        return fn(t);
    }
    catch{ }
}
return default(T2);
}

var town = staff.TryGet(x=> x.HomeAddress.Postcode.Town);

显然,这些只是抽象出逻辑并使代码(稍微)更具可读性。

但是有更好/更有效的方法吗?

编辑:

在我的特定情况下,对象是从 WCF 服务返回的,我无法控制这些对象的架构。

编辑 2:

还有这个方法:

public static class Nullify
{
    public static TR Get<TF, TR>(TF t, Func<TF, TR> f) where TF : class
    {
        return t != null ? f(t) : default(TR);
    }

    public static TR Get<T1, T2, TR>(T1 p1, Func<T1, T2> p2, Func<T2, TR> p3)
        where T1 : class
        where T2 : class
    {
        return Get(Get(p1, p2), p3);
    }

    /// <summary>
    /// Simplifies null checking as for the pseudocode
    ///     var r = Pharmacy?.GuildMembership?.State?.Name
    /// can be written as
    ///     var r = Nullify( Pharmacy, p => p.GuildMembership, g => g.State, s => s.Name );
    /// </summary>
    public static TR Get<T1, T2, T3, TR>(T1 p1, Func<T1, T2> p2, Func<T2, T3> p3, Func<T3, TR> p4)
        where T1 : class
        where T2 : class
        where T3 : class
    {
        return Get(Get(Get(p1, p2), p3), p4);
    }
}

来自这篇文章 http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/

最佳答案

最好的方法是避免违反 law of Demeter .

var town = Staff.GetTown();

Staff 中:

string GetTown()
{
    HomeAddress.GetTown();
}

HomeAddress 中:

string GetTown()
{
    PostCode.GetTown();
}

PostCode 中:

string GetTown()
{
    Town.GetTownName();
}

更新:

由于您无法控制它,您可以使用 short circuit evaluation :

if(Staff != null 
   && Staff.HomeAddress != null
   && Staff.HomeAddress.PostCode != null
   && Staff.HomeAddress.PostCode.Town != null)
{
    var town = Staff.HomeAddress.Postcode.Town;
}

关于c# - 读取对象子属性的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5744640/

相关文章:

objective-c - 具有自定义 getter 的只读属性是否会合成一个实例变量?

c# - ASP.Net 版本/内部版本号

c# - BitmapImage OutOfMemoryException 仅在 Windows 8.1 中

.net - 针对同一 VS2012 项目中的 x86 和 x64 程序集;引用

c# - .Net 中的 Async/await --> 调用没有异步实现的服务方法

javascript - 根据对象属性删除数组元素

c# - 从 C# 使用时 F# 记录类型的相等性

c# - 在 C# 中的等效结构之间高效转换

c# - 动态程序集和方法

c# - LINQ:为什么我不能在返回的对象中声明新对象?