it-swarm.com.de

Warum sollte eine generische Methode mit einer Typbeschränkung anstelle des Typs selbst verwendet werden?

In einer anderen StackExchange-Frage habe ich festgestellt, dass jemand diesen Prototyp verwendet:

void DoSomething<T>(T arg) where T: SomeSpecificReferenceType
{
    //Code....
}

Wenn man bedenkt, dass es nur eine einzige Typbeschränkung gibt (SomeSpecificReferenceType), was ist der Unterschied und der Vorteil, wenn man sie so schreibt, anstatt einfach:

void DoSomething(SomeSpecificReferenceType arg)
{
    //Code....
}

In beiden Fällen wird arg einer Typprüfung zur Kompilierungszeit unterzogen. In beiden Fällen kann sich der Hauptteil der Methode sicher auf das Wissen verlassen, dass arg von einem bestimmten Typ ist (oder von diesem abstammt), der zur Kompilierungszeit bekannt ist.

Ist dies ein Fall, in dem ein übereifriger Entwickler etwas über Generika lernt, bevor er etwas über gewöhnliche Vererbung lernt? Oder gibt es einen legitimen Grund, warum eine Methodensignatur so geschrieben wird?

14
John Wu

Ist dies ein Fall, in dem ein übereifriger Entwickler etwas über Generika lernt, bevor er etwas über gewöhnliche Vererbung lernt?

Ja, das ist es wahrscheinlich.

Oder gibt es einen legitimen Grund, warum eine Methodensignatur so geschrieben wird?

Vielleicht. Im Allgemeinen wäre es sinnvoller, wenn es einen Rückgabewert gäbe, der T betrifft, oder einen anderen Parameter, der T verwendet.

Es ist jedoch möglich, dass die Interna des Codes T (möglicherweise als Argument für einen Serializer?) Und Need verwenden, um speziell T und nicht die Constraint-Klasse zu verwenden . Sie werden gelegentlich feststellen, dass, wenn die Einschränkung eine Schnittstelle ist, die mit der Einschränkung new gepaart ist und der Mut der Methode aus irgendeinem Grund Ts erzeugt.

Obwohl es selten vorkommt, dass die erforderliche Einschränkungsversion angezeigt wird, gibt es einige Fälle, in denen dies der Fall ist. Und es ist immer möglich, dass die Methode verwendet es benötigt, aber jetzt nicht und der Entwickler hat es so belassen, wie es ist, keine brechende Änderung einzuführen.

13
Telastyn

Ich denke, ich erinnere mich, dass ich eine Antwort geschrieben habe, die diese enthält.

Zu dieser Zeit war der Grund so:
(Der Code kann unterschiedlich sein. Nur um einen der möglichen Gründe zu veranschaulichen, warum der Typparameter in einer generischen Methode eingeschränkt ist.)

class SomeSingleton
{
    static Dictionary<Type, List<object>> staticTypeSpecificList;
    public void AddObjectToList<T>(T t) where T : SomeCommonThing
    {
        Type tt = t.GetType();
        List<object> list;
        if (!staticTypeSpecificList.TryGet(tt, out list))
        {
            list = new List<object>();
            staticTypeSpecificList.Add(tt, list);
        }
        list.Add(t);
    }
}

Grundsätzlich wird der Code manuell in Typmanipulationen codiert. Es könnte auch mit einigen Reflexionsmaterialien verwechselt werden.

Wenn Sie beispielsweise Method<T>(T arg) where T : ... verwenden, können Sie arg.GetType() durch typeof(T) ersetzen. Ich weiß jedoch nicht, ob diese Wahl gut oder schlecht ist.

Ich denke, dies ist nur ein Beispiel für den Autor (möglicherweise ich oder jemand anderes) der nicht alle Möglichkeiten sorgfältig durchdacht der Codierung, wobei er sich gleichzeitig zu sehr auf eine andere Frage/ein anderes Thema konzentriert.

1
rwong