如何在带有扩展的 C# 4 中实现此功能:
string challengeId;
if(challengeId == mViewModel?.Challenge?.Id)
where Challenge.Id is string
我was given一些扩展:
public static TValue GetOrDefault<TObject, TValue>(this TObject obj, Func<TObject, TValue> getter, TValue defaultValue = default(TValue))
where TObject : class
{
return obj == null ? defaultValue : getter(obj);
}
然后我就可以这样使用它:
string challengeId;
if(challengeId == mViewModel.GetOrDefault(x => x.Challeng).GetOrDefault(x => x.Id)
在所有组合中都可以。如果 Id 不是 string
而我们想要比较 int
怎么办?
int challengeId;
if(challengeId == mViewModel.GetOrDefault(x => x.Challeng).GetOrDefault(x => x.Id)
where Challenge.Id is int
最佳答案
对于值类型,null 条件运算符返回可为 null 的值。您必须专门为返回可空值的值类型创建一个重载。
这样的事情应该有效:
public static TValue? GetOrDefault<TObject, TValue>(this TObject obj, Func<TObject, TValue> getter, TValue? defaultValue = default(TValue?))
where TObject : class
where TValue : struct
{
return obj == null ? defaultValue : getter(obj);
}
您可能需要更改名称或其他内容,因为编译器可能会发现该方法与其他重载不明确。编译器不会知道要使用哪个重载,因为它们的使用方式无法轻易区分。
例如:
mViewModel.GetOrDefault(x => x.Challenge).GetOrDefault(x => x.Id)
第二种用法是不明确的,因为编译器不清楚重载的目的是什么。通用约束不足以解决过载问题。
您必须通过指定足够的参数使编译器可以推断出哪个是正确的,指定类型参数,或者如我之前建议的那样,更改方法的名称,从而明确要使用哪个重载。
mViewModel.GetOrDefault(x => x.Challenge).GetOrDefault(x => x.Id, default(int?))
或
mViewModel.GetOrDefault(x => x.Challenge).GetOrDefault<Challenge, int>(x => x.Id)
或
mViewModel.GetReferenceOrDefault(x => x.Challenge).GetValueOrDefault(x => x.Id)
关于C# 4 中的 C# 6 nullcheck 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34563841/