接受 Expression<Func<T>> 表达式作为参数的扩展方法
Extension method that accepts Expression<Func<T>> expression as parameter
我正在使用 .NET4.5
和 C#
我想创建扩展方法,允许我传递对象的 属性,如果该对象的 ID 为 0,则 return null
否则 return 即 属性 值。
我可以通过反思来解决问题,所以考虑更多的是训练练习,而不是我试图解决实际问题。
当前扩展方法位于 static
class 中,如下所示:
public static object GetNullIfNotSet(this WillAnswer answer, Expression<Func<WillAnswer>> expression)
{
if (answer.Id == 0) return null;
return expression.Compile()();
}
我希望能够使用它的方式如下(答案类型为 WillAnswer
):
var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets)
但是它给我编译错误:
Error 1 Delegate 'System.Func' does not take 1
arguments C:\hg\Website\Areas\Wills\ViewModel\Answers.cs 38 59 Website
这让我皱眉,因为我认为我没有传递任何论点(是吗?)。请比我聪明的人解释一下我的哪些期望是错误的。
以防万一我不清楚我会重申。 我想要的是可以打电话
var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets)
并得到 null
如果 answer
的 Id
是 0
.
根本不需要Expression
,只需使用Func<WillAnswer, TProp>
:
public static TProp GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func)
{
if (answer.Id == 0) return default(TProp);
return func(answer);
}
请注意,这并不总是 return null
而是默认值(如果 属性 是值类型)。
更新(根据您的要求):
为了能够return null
所有传递的属性,方法签名改为return object
:
public static object GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func)
{
if (answer.Id == 0) return null;
return func(answer);
}
但是,您将失去泛型的好处,并且最终会显式转换为 Nullable<T>
:
var emptyIfNewObject = (bool?)answer.GetNullIfNotSet(o => o.HasBusinessAssets)
不太理想。
您似乎需要 Func<WillAnswer, T>
而不是 表达式:
public static T GetDefaultIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func) {
if (null == answer)
throw new ArgumentNullException("answer");
else if (null == func)
throw new ArgumentNullException("func");
return answer.Id == 0 ? return default(T) : func(answer);
}
编辑:如果你想确保 null
你可以限制泛型T
:
public static T GetNullIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func)
where T: class { // no structs here
if (null == answer)
throw new ArgumentNullException("answer");
else if (null == func)
throw new ArgumentNullException("func");
return answer.Id == 0 ? return null : func(answer);
}
是的,你可以:
public static void LoadProperty<T>(this T t, Func<T, object> func) where T: Entity
{
}
你可以使用:
contact.LoadProperty(p => p.LogicalName);
我正在使用 .NET4.5
和 C#
我想创建扩展方法,允许我传递对象的 属性,如果该对象的 ID 为 0,则 return null
否则 return 即 属性 值。
我可以通过反思来解决问题,所以考虑更多的是训练练习,而不是我试图解决实际问题。
当前扩展方法位于 static
class 中,如下所示:
public static object GetNullIfNotSet(this WillAnswer answer, Expression<Func<WillAnswer>> expression)
{
if (answer.Id == 0) return null;
return expression.Compile()();
}
我希望能够使用它的方式如下(答案类型为 WillAnswer
):
var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets)
但是它给我编译错误:
Error 1 Delegate 'System.Func' does not take 1 arguments C:\hg\Website\Areas\Wills\ViewModel\Answers.cs 38 59 Website
这让我皱眉,因为我认为我没有传递任何论点(是吗?)。请比我聪明的人解释一下我的哪些期望是错误的。
以防万一我不清楚我会重申。 我想要的是可以打电话
var emptyIfNewObject = answer.GetNullIfNotSet(o => o.HasBusinessAssets)
并得到 null
如果 answer
的 Id
是 0
.
根本不需要Expression
,只需使用Func<WillAnswer, TProp>
:
public static TProp GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func)
{
if (answer.Id == 0) return default(TProp);
return func(answer);
}
请注意,这并不总是 return null
而是默认值(如果 属性 是值类型)。
更新(根据您的要求):
为了能够return null
所有传递的属性,方法签名改为return object
:
public static object GetNullIfNotSet<TProp>(this WillAnswer answer, Func<WillAnswer, TProp> func)
{
if (answer.Id == 0) return null;
return func(answer);
}
但是,您将失去泛型的好处,并且最终会显式转换为 Nullable<T>
:
var emptyIfNewObject = (bool?)answer.GetNullIfNotSet(o => o.HasBusinessAssets)
不太理想。
您似乎需要 Func<WillAnswer, T>
而不是 表达式:
public static T GetDefaultIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func) {
if (null == answer)
throw new ArgumentNullException("answer");
else if (null == func)
throw new ArgumentNullException("func");
return answer.Id == 0 ? return default(T) : func(answer);
}
编辑:如果你想确保 null
你可以限制泛型T
:
public static T GetNullIfNotSet<T>(this WillAnswer answer, Func<WillAnswer, T> func)
where T: class { // no structs here
if (null == answer)
throw new ArgumentNullException("answer");
else if (null == func)
throw new ArgumentNullException("func");
return answer.Id == 0 ? return null : func(answer);
}
是的,你可以:
public static void LoadProperty<T>(this T t, Func<T, object> func) where T: Entity
{
}
你可以使用:
contact.LoadProperty(p => p.LogicalName);