views:

535

answers:

3

Hi

I was wondering if it is possible, as my 5 minutes of experimentation proved fruitless.

I hoped it would be as easy as:

T Identity<T>(T t) { return t; }

But this fails to compile on generic methods taking Func parameters. Eg OrderBy. Even specifying type parameters (which is exactly what I want to avoid!), it fails to compile.

Next I tried something I thought would work:

Func<T, R> MakeIdentity<T, R>()
{
  return (T t) => (R)(object)t;
}

Also no go :( (this compiles when applying type parameters, again, not what I want)

Has anyone had luck making such a thing?

UPDATE: please dont say: x => x, I know that, it's obvious! I am asking for a function, not an expression :)

UPDATE 2: When I refer to identity, I mean in the functional sense, where the function simply returns the same object that you passed to it. It is probably in every functional language I have come across, but those do not use static typing. I am wondering how to do this (if possible) with generics. Just for fun!

UPDATE 3: Here's a partial 'solution' based on the 2nd idea:

Expression<Func<T, T>> MakeIdentity<T>()
{
  return t => t;
}

void Foo(string[] args)
{
  var qargs = args.AsQueryable();
  var q = qargs.OrderBy(MakeIdentity<string>());
  ...
}

I dont think anything more than this will be possible.

+1  A: 

The problem you're having is that anonymous functions and method groups in C# do not participate in type inference. Explicit types must be given.

What you can do though is have Identity functions for anonymous functions. Example

Func<T> IdentityFunc1<T>(Func<T> func) { return func; }

I'm not entirely sure what you're getting at with the second sample. Can you elaborate?

JaredPar
I think you understand identity wrong. It's a commonly used function in functional language, that simply returns what you give it.
leppie
I think your answer still applies though, thanks :)
leppie
A: 

I don't think that you can do this. From MSDN:

The same rules for type inference apply to static methods as well as instance methods. The compiler is able to infer the type parameters based on the method arguments you pass in; it cannot infer the type parameters solely from a constraint or return value.

So the following will work

myList.OrderBy(i => Identity<int>(i));

but the following will not

myList.OrderBy(Identity<int>);
Jason
What about the second option? I realise by Jared's answer, that the first case is not possible.
leppie
+2  A: 

Type inference will not work since host method and input method both are generic. To do this you must write

myList.OrderBy<int, int>(Identity);

Or

myList.OrderBy((Func<int, int>)Identity);
chaowman