Навіщо використовувати загальний метод із обмеженням типу замість самого типу?


14

У іншому запитанні StackExchange я помітив, хто використовує цей прототип:

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

Маючи на увазі, є лише обмеження одного типу ( SomeSpecificReferenceType), яка різниця і перевага писати це так, а не просто:

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

В обох випадках argбуде підлягати перевірка типу компіляції за часом. В обох випадках тіло методу може спокійно покладатися на знання, що argє (або є нащадком) конкретного типу, що відомо під час компіляції.

Це випадок надмірного розробника, який вивчає генеричні засоби, перш ніж дізнатися про звичайне успадкування? Або є законна причина, чому підпис методу був би написаний таким чином?


Я ледве знаю C #, тому це лише здогадка, але чи не це дозволяє більш ефективною статичною відправою замість динамічної?
Антон Барковський

Відповіді:


13

Це випадок надмірного розробника, який вивчає генеричні засоби, перш ніж дізнатися про звичайне успадкування?

Так, мабуть, так і є.

Або є законна причина, чому підпис методу був би написаний таким чином?

Можливо . Як правило, було б більше сенсу, якби було повернене значення, яке було пов'язано T, або інший параметр, який використовується T.

Але можливо, що внутрішні коди використовують T(можливо, як аргумент серіалізатору?) І потрібно використовувати конкретно, Tа не клас обмеження. Ви час від часу побачите, що коли обмеження є інтерфейсом, сполученим із newобмеженням, а кишки методу створюютьT s чомусь.

Тож, хоча рідко можна побачити необхідну версію обмеження, є деякі випадки, коли вона є. І завжди можливо, що раніше потрібен метод , але зараз цього немає, і розробник покинув це так, як не вводити переломних змін.


1

Я думаю, що я пам’ятаю, що я вводив відповідь, що містить це.

У той час причина була така:
(Код може бути різним. Просто для ілюстрації однієї з можливих причин, чому в загальному методі існує обмеження параметру типу.)

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

В основному код потрапляє в маніпуляції типу кодування вручну. Це також може бути змішане з деякими рефлексійними матеріалами.

Наприклад, використовуючи Method<T>(T arg) where T : ..., його можна замінити arg.GetType()на typeof(T). Хоча я не знаю, хороший чи поганий цей вибір.

Напевно, це лише приклад того, що автор (можливо, я чи хтось інший) не ретельно продумав усі можливості кодування, водночас занадто сильно зосередившись на іншому питанні / питанні.


"можна замінити arg.GetType () на typeof (T)". Це корисно, коли аргумент може бути нульовим, наприклад у деяких випадках серіалізації.
пройти
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.