Let's say I have a type:
public class Transformer<T, TResult>
where T : IMessage
where TResult : IMessage
{
private Func<T, IEnumerable<TResult>> _transformer;
public Transformer(Func<T, TResult> transformer)
{
_transformer = null // ?
}
public Transformer(Func<T, IEnumerable<TResult>> transformer)
{
_transformer = transformer;
}
}
So in essence, I'd like to convert Func<T, T开发者_运维问答Result>
into Func<T, IEnumerable<TResult>>
in the first constructor.
I've tried to create a private inner class that takes Func<T, TResult>
and defined a method that returns IEnumerable like this:
private class TransformerWrapper
{
private readonly Func<T, TResult> _func;
public TransformerWrapper(Func<T, TResult> func)
{
_func = func;
}
public IEnumerable<TResult> Transform<T>(T message) where T : IMessage
{
yield return _func(message);
}
}
But it's not really working out. I get an error saying delegate has an invalid argument - cannot convert from T to T.
First of all, what is happening with the compiler error and second, is there another way?
Update
Minutes after I posted, I found a solution:
public Transformer(Func<T, TResult> transformer)
{
_transformer = new TransformerWrapper<T, TResult>(transformer).Transform;
}
And,
private class TransformerWrapper<T, TResult>
{
private readonly Func<T, TResult> _func;
public TransformerWrapper(Func<T, TResult> func)
{
_func = func;
}
public IEnumerable<TResult> Transform(T message)
{
yield return _func(message);
}
}
I still can't get my head around why the first solution did not work. I need to think about that one...
Try this:
public Transformer(Func<T, TResult> transformer)
{
_transformer = t => Convert(t, transformer);
}
private static IEnumerable<TResult> Convert(T value, Func<T, TResult> transformer)
{
yield return transformer(t);
}
You're specifying a new generic type T
in the Transform<T>
function. As T
and TResult
are already defined in the parent class, there's no need for anything in the child class to be generic.
Remove the <T>
and the generic qualifier from the method signature and it should compile.
public IEnumerable<TResult> Transform(T message)
{
yield return _func(message);
}
Change your inner class to:
private class TransformerWrapper
{
private readonly Func<T, TResult> _func;
public TransformerWrapper(Func<T, TResult> func)
{
_func = func;
}
public IEnumerable<TResult> Transform(T message)
{
yield return _func(message);
}
}
}
Compile already knows what T is, and you don't need to constrain the method again.
精彩评论