Warum eine generische Methode mit einer Typbeschränkung anstelle des Typs selbst verwenden?


14

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 es so schreibt, anstatt einfach:

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

In beiden Fällen argwird eine Typprüfung zur Kompilierungszeit durchgeführt. In beiden Fällen kann sich der Hauptteil der Methode sicher auf Wissen stützen, das zu argeinem bestimmten Typ gehört (oder von diesem abstammt), der zum Zeitpunkt der Kompilierung bekannt ist.

Ist dies ein Fall, in dem ein übereifriger Entwickler zuerst etwas über Generika und dann über die normale Vererbung erfährt? Oder gibt es einen berechtigten Grund, warum eine Methodensignatur so geschrieben würde?


Ich kenne C # kaum, also ist dies nur eine Vermutung, aber ermöglicht dies nicht einen effizienteren statischen Versand anstelle eines dynamischen Versands?
Anton Barkovsky

Antworten:


13

Ist dies ein Fall, in dem ein übereifriger Entwickler zuerst etwas über Generika und dann über die normale Vererbung erfährt?

Ja, das ist es wahrscheinlich.

Oder gibt es einen berechtigten Grund, warum eine Methodensignatur so geschrieben würde?

Vielleicht . Im Allgemeinen wäre es sinnvoller, wenn ein Rückgabewert Toder ein anderer verwendeter Parameter vorhanden wäre T.

Aber es ist möglich , dass die Einbauten des Codes verwenden T(vielleicht als Argument für einen Serializer?) Und müssen speziell verwenden Tund nicht die Einschränkung Klasse. Sie werden gelegentlich feststellen, dass, wenn die Einschränkung eine mit der newEinschränkung gepaarte Schnittstelle ist und die Eingeweide der Methode Taus irgendeinem Grund s erzeugen.

Es ist zwar selten, die benötigte Einschränkungsversion zu sehen, aber manchmal ist dies der Fall. Und es ist immer möglich, dass die verwendete Methode es benötigt, aber jetzt nicht und der Entwickler hat es so belassen, dass keine brechende Änderung eingeführt wird.


1

Ich glaube, ich erinnere mich, dass ich eine Antwort geschrieben habe, die dies enthält.

Zu dieser Zeit lautete der Grund folgendermaßen:
(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 in die manuelle Codierung von Typmanipulationen selbst einbezogen. Es könnte auch mit etwas Reflexionsmaterial verwechselt werden.

Zum Beispiel Method<T>(T arg) where T : ...kann man arg.GetType()mit ersetzen typeof(T). Allerdings weiß ich nicht, ob diese Wahl gut oder schlecht ist.

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


msgstr "man kann arg.GetType () durch typeof (T) ersetzen". Dies ist nützlich, wenn arg gültig null sein kann, z. B. in einigen Serialisierungsfällen.
Walpen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.