Обобщенный тип и неявное\явное указание типа

243
23 декабря 2016, 11:11

К примеру имеется два метода, которые выглядят достаточно тривиально,но возникает вопрос,можно ли назвать их следующим образом:

// Обобщенный тип с неявным указанием типа, и соответственно 
// так писать можно(никаких синтаксическим ошибок в коде нет)
void Method(T arg);  

и такой

void Method<T>(T arg); // Обобщенный тип с явным указанием типа

То бишь, по сути, оба метода идентичны (и соответственно являются Обобщенными или же все таки в первом случае,мы не можем сказать, что метод обобщенный(невзирая на то,что у него есть параметризованный аргумент)?

UPD
Забыл уточнить момент,что выше перечисленные методы находятся в обобщенном интерфейсе или классе, т.е.

interface IFly<T>
{
    void Method<T>(T arg); //так
    void Method(T arg); // или так
}
Answer 1

Обобщенными могут быть:

  • Отдельные методы
  • Классы и структуры

В первом случае мы можем так указать, только если сам класс, к которому принадлежит метод, является обобщенным и содержит заполнитель (параметр типа) T:

public class MyGenericClass<T>
{
    public void Method(T arg)
    {
        // ...
    }
}

Во втором случае у вас обобщенный метод:

public class MyClass
{
    public void GenericMethod<T>(T arg)
    {
        // ...
    }
}

По вопросу

Если к методу в обобщенном классе добавить свои заполнители, то потеряется безопасность в отношении типов. Поэтому обобщенные методы нужно размещать в не обобщенных классах.

Что имеется ввиду под безопасность. Возьмем приведенный выше класс MyGenericClass. Мы можем создать его объект и вызвать метод:

var obj = new MyGenericClass<int>();
obj.Method(5);

В данном случае метод отработает так, как мы и ожидаем. Ничего кроме int в метод передать не получится, иначе возникнет ошибка на этапе компиляции.

Теперь дополнительно параметризируем сам метод:

public class MyGenericClass<T>
{
    public void GenericMethod<T>(T arg)
    {
        // ...
    }
}

Поведение метода стало не очевидным:

var obj = new MyGenericClass<int>();
obj.Method("blabla"); // Ошибки времени компиляции не возникнет
                      // т.к. будет неявно использоваться обобщенный тип метода
Answer 2

Если у вас есть такой код:

interface IFly<T>
{
    void Method<T>(T arg); //так
    void Method(T arg); // или так
}

То здесь второе объявление T перекрывает первое. На самом деле, приведенный вами код эквивалентен следующему:

interface IFly<A>
{
    void Method<B>(B arg); //так
    void Method(A arg); // или так
}

Обычно подобное перекрытие является ошибкой, потому что зачем-то ведь параметр типа был объявлен. К примеру, код ниже не скомпилируется из-за несоответствия типов:

class Foo<T>
{
    T value;
    public void SetValue<T>(T arg) {
        value = arg; // ошибка компиляции
    }
}

Кстати, два уровня перекрытия идентификаторов - не предел. Не делайте так:

class Foo<T> {
    class Bar<T> {
        class Baz<T> {
            void Method<T>();
        }
    }
}

В примере выше все 4 буквы T обозначают разные типы.

READ ALSO
Исключения при создании объекта класса [требует правки]

Исключения при создании объекта класса [требует правки]

Народ, есть класс - прямоугольный треугольникКак, вопрос, максимально профессионально отлавливать исключения - "где и когда" - если, например,...

316
Получить текст сылками на картинки в anglesharp

Получить текст сылками на картинки в anglesharp

Допустим, имеется страница, где в тексте есть картинки

279