N.D*_*D.B 11 c# extension-methods
是否可以在C#5.0中创建一些扩展方法,以提供与C#6.0 Elvis(?.)运算符相同的结果?
例如:
//C# 6.0 way
var g1 = parent?.child?.child?.child;
if (g1 != null) // TODO
//C# 5.0 way
var g1 = parent.elvisExtension().child.elvisExtension().child.elvisExtension().child;
if (g1 != null) // TODO
Run Code Online (Sandbox Code Playgroud)
有可能使用与mocking相同的方法(parent它不会返回,而是返回父级的'mock',它将返回null或对象值).但是,这有点复杂.
这非常简单,并且可以使用基本功能:
public static class Helper
{
public static TReturnType Elvis<TOnType, TReturnType>(this TOnType onObj, Func<TOnType, TReturnType> selector)
where TReturnType : class
{
if (onObj == null)
return null;
return selector(onObj);
}
}
Run Code Online (Sandbox Code Playgroud)
测试它:
var person = new Person { Parent = new Person { Parent = new Person() } };
var result = person.Elvis(p => p.Parent).Elvis(p => p.Parent);
Run Code Online (Sandbox Code Playgroud)
正确获取Person对象.
person = new Person();
result = person.Elvis(p => p.Parent).Elvis(p => p.Parent);
Run Code Online (Sandbox Code Playgroud)
返回null.
但是,这仅适用于可空类型.不幸的是,你不能创建一个重载where TReturnType : struct,我们需要一个新的方法来处理它.
因此,对于非可空类型,我们需要这样:
public static TReturnType? Elviss<TOnType, TReturnType>(this TOnType onObj, Func<TOnType, TReturnType> selector)
where TReturnType : struct
{
if (onObj == null)
return default(Nullable<TReturnType>);
return selector(onObj);
}
Run Code Online (Sandbox Code Playgroud)
并测试它:
var result = person.Elvis(p => p.Parent).Elviss(p => p.Id);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1023 次 |
| 最近记录: |