有没有办法将泛型方法实现为一个泛型类型,它接受另一个类型的Func参数?
例如,使用类似于此的用法:
myFirstObject.Extension<myOtherObject>( other => other.Prop );
或者使用更复杂的Func:
myFirstObject.Extension<myOtherObject>( other => other.Prop > 2 && other.Prop < 15 );
我发现了一些像this one这样的相关问题,但就我而言,我也需要扩展方法中的泛型类型。
以下是我提出的建议:
public static bool Extension<TSource, TIn, TKey>(this TSource p_Value, Expression<Func<TIn, TKey>> p_OutExpression)
{ return true; }
但是,当我尝试使用它时,它没有考虑第二种类型。
我错过了什么吗?
答案 0 :(得分:3)
看看这个:
s => s.Length;
编译器如何知道s
是string
还是s
是一个数组还是其他具有Length
属性的类型?它不能,除非你给它一些信息:
(string s) => s.Length;
哦,我们走了。现在,试试这个:
myFirstObject.Extension((myOtherObject o) => o.Prop > 2 && o.Prop < 15);
这样可行,因为你告诉编译器它应该用于TIn
,它可以根据表达式找出TKey
的用途。
答案 1 :(得分:0)
当您在C#中调用泛型方法时,您可以显式声明所有泛型类型参数,或者可以将它们全部推断出来,但是您不能有一些显式声明和一些推断。
所以,如果我有这个方法:
public void Foo<X, Y>(X x, Y y)
{
/* Do somethhing */
}
然后这是有效的,有效的是什么:
int a = 42;
string b = "Hello, World!";
// Legal
Foo(a, b);
Foo<int, string>(a, b);
//Illegal
Foo<int>(a, b);
您可以做的最好的事情是将第一个通用参数移到类级别,但不会将它作为扩展方法。不过你可能会喜欢这种方法。
public static class Class<TSource>
{
public static bool Method<TIn, TKey>(
TSource p_Value,
Expression<Func<TIn, TKey>> p_OutExpression)
{
return true;
}
}
现在你可以这样称呼它:
Expression<Func<long, decimal>> f =
l => (decimal)l;
var result = Class<int>.Method(a, f);
但正如我所说,它现在不能作为一种扩展方法。
答案 2 :(得分:0)
我发现另一个解决方案是创建另一个接受参数类型的方法。
例如:
Void Extension(Type p_Type, [THE TYPE] p_Params)
{
MethodInfo realExtensionMethod = typeof([CLASS CONTAINING THE METHOD]).GetMethod("RealExtension");
realExtensionMethod = realExtensionMethod.MakeGenericMethod(p_Type);
realExtensionMethod.Invoke(null, new object[] {p_Type, p_Params });
}
Void RealExtension<TYPE>(params)
{
}
然后在使用时间:
Type objectType = typeof(myOtherObject);
myFirstObject.Extension(objectType, other => other.Prop );