2

有没有办法实现对泛型类型的扩展方法,该泛型类型接受另一种类型的 Func 参数?

例如,类似这样的用法:

myFirstObject.Extension<myOtherObject>( other => other.Prop );

或者使用更复杂的 Func:

myFirstObject.Extension<myOtherObject>( other => other.Prop > 2 && other.Prop < 15 );

我发现了一些类似的相关问题但就我而言,我也需要扩展方法中的泛型类型。

这是我想出的:

public static bool Extension<TSource, TIn, TKey>(this TSource p_Value, Expression<Func<TIn, TKey>> p_OutExpression) 
{ return true; }

但是,当我尝试使用它时,它并没有考虑到第二种类型。

我错过了什么吗?

4

3 回答 3

3

看这个:

s => s.Length;

编译器如何知道s是 astring还是s数组或其他具有Length属性的类型?它不能,除非你给它一些信息:

(string s) => s.Length;

哦,我们走了。所以现在,试试这个:

myFirstObject.Extension((myOtherObject o) => o.Prop > 2 && o.Prop < 15);

这将起作用,因为您已经告诉编译器它应该用于什么TIn,并且它可以TKey根据表达式确定要使用什么。

于 2013-07-25T21:42:39.830 回答
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);

但正如我所说,它现在不能用作扩展方法。

于 2013-07-26T00:31:19.433 回答
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 );
于 2013-07-26T18:09:36.667 回答