Perché utilizzare un metodo generico con un vincolo di tipo anziché il tipo stesso?

9

In una domanda StackExchange diversa, ho notato qualcuno che utilizza questo prototipo:

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

Tenendo presente che esiste un solo vincolo di tipo ( SomeSpecificReferenceType ), qual è la differenza e il vantaggio di scriverlo in quel modo, invece di semplicemente:

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

In entrambi i casi, arg sarà soggetto al controllo del tipo in fase di compilazione. In entrambi i casi, il corpo del metodo può fare affidamento sulla conoscenza che arg è di (o è un discendente di) un tipo specifico che è noto al momento della compilazione.

Si tratta di un caso di uno sviluppatore troppo zelante che sta imparando i farmaci generici prima di apprendere l'ereditarietà ordinaria? O esiste una ragione legittima per cui una firma di metodo dovrebbe essere scritta in questo modo?

    
posta John Wu 28.02.2017 - 03:01
fonte

2 risposte

10

Is this a case of an overzealous developer learning about generics before learning about ordinary inheritance?

Sì, probabilmente lo è.

Or is there a legitimate reason why a method signature would be written this way?

Forse . In generale, avrebbe più senso se ci fosse un valore di ritorno che riguardava T , o un altro parametro che ha usato T .

Tuttavia, è possibile che le parti interne del codice utilizzino T (forse come argomento per un serializzatore?) e bisogno per usare specificamente T e non la classe constraint. Occasionalmente lo vedrai quando il vincolo è un'interfaccia accoppiata con il vincolo new e le viscere del metodo creano T s per qualche motivo.

Quindi, mentre è raro vedere la versione del vincolo necessaria, ci sono alcune volte quando lo è. Ed è sempre possibile che il metodo usato ne abbia bisogno, ma ora non lo fa e lo sviluppatore lo ha lasciato così com'è da non introdurre una modifica di rottura.

    
risposta data 28.02.2017 - 03:15
fonte
1

Penso di essermi ricordato di digitare una risposta contenente questo.

In quel momento la ragione era questa:
(Il codice potrebbe essere diverso. Solo per illustrare uno dei possibili motivi per cui esiste un vincolo sul parametro type in un metodo generico.)

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);
    }
}

Fondamentalmente, il codice entra manualmente nella manipolazione dei tipi di codice. Potrebbe anche essere mescolato con alcune cose di riflessione.

Ad esempio, utilizzando Method<T>(T arg) where T : ... , è possibile sostituire arg.GetType() con typeof(T) . Però, non so se quella scelta sia buona o cattiva.

Immagino che questo sia solo un esempio dell'autore (forse io o qualcun altro) non pensando attentamente a tutte le possibilità di codifica, allo stesso tempo concentrandoti troppo su una domanda diversa / problema.

    
risposta data 28.02.2017 - 03:43
fonte

Leggi altre domande sui tag