-2

I tried to code a function using refelecion to convert a function Func< TSource, bool> to Func< TTarget, bool> but without success

This what i did:

static Func<TTarget, bool> Convert<TSource, TTarget>(Func<TSource, bool> func)
    {
        var result = func;
        result.GetType().GenericTypeArguments[1] = typeof(TTarget);
        return (Func<TTarget, bool>)result;
    } 

Edit:

In my case i've an object User as a DTO and don't want to share this DTO with other layers, it will be visible only by my service agent, Then, there is another Layer which has access to my service agent, in this layer i've another Object that represent a user let's say 'CustomUser'. Let's say that the different between 'User' and 'CutomUser' that the first has a property 'Password' and the second without it.

In my service agent, i've a function GetUser( Func< User, bool> func ) but in my 3rd party layer i can't see the object User, however, the object CustomUser is visible So, in my service agent layer, i want to create another function GetUser ( Func< CustomUser, bool >) that will be visible by other layers and this function calls directly the first hidden function GetUser(Func< User, bool> ) by using a converter

public CustomUser GetUser(Func<CustomUser, bool> func) {
    // var myUser = this.GetUser(ConvertFunc( func) ) ;
    // The rest of code before returning my customUser
}
SomeCode.NET
  • 917
  • 15
  • 33
  • 1
    What would this even mean? If `func` takes a `TSource`, then it takes a `TSource`. Pretending it takes a `TTarget` probably isn't going to end well. – Oliver Charlesworth Sep 28 '14 at 20:06
  • This doesn't make sense, unless there's more context to this. – Theodoros Chatzigiannakis Sep 28 '14 at 20:07
  • @OliverCharlesworth why not possible? if i've a function with one arguement Func then i invoke it as the following: MyFunction(u=> u.Id == 1) then if i convert my Func to Func the invoke method stills the same because i've the same properties in both User and CustomUser – SomeCode.NET Sep 28 '14 at 20:14
  • 2
    If `CustomUser` extends from `User`, then no conversion is necessary. – Oliver Charlesworth Sep 28 '14 at 20:15
  • @OliverCharlesworth i know that, but CustomUser doesn't, if it is possible to convert an expression why not a Func? take a look at this [Faster way to cast a Func to Func](http://stackoverflow.com/questions/654153/c-sharp-how-to-convert-an-expressionfuncsometype-to-an-expressionfuncother) – SomeCode.NET Sep 28 '14 at 20:17
  • 1
    Without a where clause to ensure `TSource` and `TTarget` implement something similar, you can't do what you want because you can't guarantee `Func` is compatible with `Func`. Maybe if you explain why you *think* you need to do this, someone might be able to help with *that*. – Peter Ritchie Sep 28 '14 at 20:25
  • @cYounes Because the whole point of expression trees is that code can investigate precisely what the expression looks like. If you could do that with arbitrary methods, we wouldn't have needed expression trees in the first place. –  Sep 28 '14 at 20:25
  • 1
    If `CustomerUser` is not a `User` and you still want to treat it like one (and you're sure it's going to work), better try working around the problem using `dynamic` typing. There's no point trying to bypass the static type system using sneaky tricks, because (a) it's not as easy as it sounds and (b) you can easily opt out of it in newer versions of the language. – Theodoros Chatzigiannakis Sep 28 '14 at 20:28
  • @PeterRitchie Just explained the situation in edited post – SomeCode.NET Sep 28 '14 at 20:37
  • 1
    @cYounes You can't do what you want without sharing something across layers. It appears what you really want is something dynamic dispatch. (http://en.wikipedia.org/wiki/Dynamic_dispatch) Probably al;sorts of good questions on SO about this http://stackoverflow.com/search?q=dynamic+dispatch+%5Bc%23%5D – Peter Ritchie Sep 28 '14 at 20:41
  • 1
    @cYounes you need something like `Func userFunc = u=>func(UserToCustomUser(u))` and after use `this.GetUser(userfunc )`, but you should have `UserToCustomUser` function which can map user object to customeruser object – Grundy Sep 28 '14 at 20:43
  • @Grundy i've alreay a function UserToCustomUser defined, Can you just clarify please? :) – SomeCode.NET Sep 28 '14 at 21:34
  • 1
    @cYounes what you need clarify? i already show sample `Func userFunc = u=>func(UserToCustomUser(u))` – Grundy Sep 29 '14 at 06:09
  • @Grundy Thanks a lot, your solution works correctly, you can write an answer to be marked as solution :) – SomeCode.NET Sep 29 '14 at 18:20

2 Answers2

1

You're trying to convert a Func<TSource, bool> into a Func<TTarget, bool>, without any other details or constraints.

Consider the case where TSource is a string and TTarget is an XmlDocument. A method that fits the first delegate is string.StartsWith(string) and a method that fits the second delegate is List<XmlDocument>.Contains(XmlDocument).

So, when you do the following (a valid call, if we suppose your code was valid):

var converted = Convert<string, XmlDocument>("String".StartsWith);

And then you call:

var result = converted.Invoke(new XmlDocument());

What do you think will happen? What do you aim to happen?

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
  • as i said in a comment above, if it's possible to convert an expression why not a func? [Faster way to cast a Func to Func](http://stackoverflow.com/questions/2169062/faster-way-to-cast-a-funct-t2-to-funct-object) – SomeCode.NET Sep 28 '14 at 20:20
  • 1
    @cYounes Off the top of my head, I'd say it's because the last type parameter is covariant (but the others aren't). Take a look at its definition (notice the `out` keyword): http://msdn.microsoft.com/en-us/library/bb549151(v=vs.110).aspx – Theodoros Chatzigiannakis Sep 28 '14 at 20:22
  • 2
    @cYounes because Func already compiled, but expression just syntax tree that you can change as you wish – Grundy Sep 28 '14 at 20:22
1

Finally, The solution of @Grundy works for me correctly, I've just to create a function that convert an object User to CustomUser then i do the following:

Func<User,bool> userFunc = u=>func(UserToCustomUser(u))
this.GetUser(userfunc) 
SomeCode.NET
  • 917
  • 15
  • 33