Из вашего вопроса неясно, в чем именно заключается ваша проблема, но я могу предположить, что приведение Func<T1, T2>
к Func<T1, int>
дает недопустимую ошибку приведения.
Причина, по которой это неверно, заключается в том, что C # консервативен в отношении любого преобразования параметра типа в любой другой тип.Предположим, у вас есть пользовательское преобразование из Foo в Bar.Если у вас есть метод
Bar M<T>(T t) { return (Bar)t; }
, вы можете разумно ожидать, что M<Foo>(new Foo())
вызовет пользовательское преобразование в Bar
.Но дженерики C # не являются шаблонами и не воссоздают код для каждого родового экземпляра.Этот вид преобразования действителен только в том случае, если имеется удостоверение или ссылка преобразование, и C # не позволяет вам совершить эту распространенную ошибку.
Более того, в любое времявы делаете типовой тест для универсального, он больше не «универсальный» .Предполагается, что общий код должен работать одинаково независимо от аргументов типа , поэтому он называется «универсальный код».Похоже, то, что вы делаете, работает против с целью генериков.
Тем не менее, если вы одержимы этим, есть несколько способов сделать эталонное преобразование междуобщие типы, подобные этому:
class C<T1, T2>
{
void M(Func<T1, int> f) {}
// This way is wrong.
void N1(Func<T1, T2> f)
{
if (f is Func<T1, int>)
M((Func<T1, int>)f); // Error, cannot convert
}
// This works.
void N2(Func<T1, T2> f)
{
var fi = f as Func<T1, int>;
if (fi != null)
M(fi);
}
// This also works.
void N3(Func<T1, T2> f)
{
if (f is Func<T1, int>)
M((Func<T1, int>)(object)f);
}
// This works in C# 7; it's a more concise way to combine the previous two
void N4(Func<T1, T2> f)
{
if (f is Func<T1, int> fi)
M(fi);
}
}