11 Stimmen

Generische Identitätsfunktion zur Verwendung bei der Typinferenz

Ich habe mich gefragt, ob das möglich ist, denn meine 5 Minuten Experimentierzeit waren erfolglos.

Ich hoffte, es würde so einfach sein wie:

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

Bei generischen Methoden mit Func-Parametern lässt sich dies jedoch nicht kompilieren. Z.B. OrderBy. Selbst die Angabe von Typ-Parametern (was genau das ist, was ich vermeiden möchte!), es schlägt fehl zu kompilieren.

Als Nächstes habe ich etwas ausprobiert, von dem ich dachte, es würde funktionieren:

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

Auch nicht gehen :( (dies kompiliert bei der Anwendung von Typ-Parameter, wieder, nicht das, was ich will)

Hatte jemand Glück bei der Herstellung eines solchen Dings?

UPDATE: Bitte sagen Sie nicht: x => x, ich weiß das, es ist offensichtlich! Ich frage nach einer Funktion, nicht nach einem Ausdruck :)

UPDATE 2: Wenn ich von Identität spreche, meine ich das im funktionalen Sinne, bei dem die Funktion einfach das gleiche Objekt zurückgibt, das man ihr übergeben hat. Das gibt es wahrscheinlich in jeder funktionalen Sprache, die mir begegnet ist, aber diese verwenden keine statische Typisierung. Ich frage mich, wie man dies (wenn möglich) mit generischen Funktionen erreichen kann. Nur so zum Spaß!

UPDATE 3: Hier ist eine Teillösung, die auf der zweiten Idee basiert:

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

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

Ich glaube nicht, dass mehr als dies möglich sein wird.

0 Stimmen

Ich bin es leid, x => x zu schreiben :) Und ich frage mich nur, ob es wirklich keinen Zweck hat.

0 Stimmen

Mit C# 6.0 myList.OrderBy(Identity); wird funktionieren.

3voto

Die Typinferenz funktioniert nicht, da sowohl die Wirtsmethode als auch die Eingabemethode generisch sind. Um dies zu tun, müssen Sie schreiben

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

Oder

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

2voto

Ostati Punkte 4377

Das funktioniert für mich an den Stellen, an denen ich es bisher gebraucht habe.

internal class IdentityFunction<TSource>
{
    public static Func<TSource, TSource> Instance
    {
        get { return x => x; }
    }
}

OrderBy(IdentityFunction<Foo>.Instance)

1voto

JaredPar Punkte 699699

Das Problem, das Sie haben, ist, dass anonyme Funktionen und Methodengruppen in C# nicht an der Typinferenz teilnehmen. Es müssen explizite Typen angegeben werden.

Was Sie jedoch tun können, ist Identitätsfunktionen für anonyme Funktionen zu haben. Beispiel

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

Ich bin mir nicht ganz sicher, worauf Sie mit dem zweiten Beispiel hinauswollen. Können Sie das näher erläutern?

0voto

onof Punkte 16911

Die erste Option funktioniert für mich:

public class Foo {

   public Foo(Func<MyObj, MyObj> map) {... }

}

public class Client {

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

   public void main() {
      var foo = new Foo(Identity);

      var c = from f in Enumerable.Range(0, 100) select Identity(f);
      c.ToList().ForEach(System.Console.Out.WriteLine);
   }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X