假设您正在尝试读取此属性
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/