Статические классы не могут быть генериками


#1

Почему поставлено такое ограничение?

type
  TClass<T> = static class // Program3.pas(2) : Статические классы не могут быть генериками
  end;

begin
end.

В C# аналогичный код компилируется:

using System;
 
namespace ConsoleApp1
{
	static class C<T>
	{
	}
	
    static class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

. Если Вы проверяли реакцию компиляторов других языков, то было не лишним выложить результаты тестов.

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

	static class SomeClass<T>
	{
		public static void A() // Как-то используем T.
		{
		}
		
		public static void B() // Как-то используем T.
		{
		}
	}

, с:

	static class SomeClass
	{
		public static void A<T>() // Как-то используем T.
		{
		}
		
		public static void B<T>() // Как-то используем T.
		{
		}
	}

, Тем, более, если на T должны накладываться какие-либо ограничения, которые едины для методов данного класса, то было бы удобней перечислять их в where класса, а не каждого метода.


#2

Потому что тип шаблонного класса определяется при создании экземпляра класса. Экземпляр статического класса создать нельзя, как и наследовать от класса.


#3

Если это особенность именно PascalABC.Net, то это весомый аргумент. Но, напомню, что в C# мы наблюдаем противоположное поведение - статические классы могут быть шаблонными.


#4

Ну нельзя же везде и во всём следовать C#.


#5

Согласен.

<личное мнение>И так достаточно оттуда позаимствовали. Лично для меня теперь всего хватает.</личное мнение>

Если разработчики подтвердят, что это действительно особенность данного компилятора, то вопрос можно будет считать закрытым.

<личное мнение>Думаю, что эту тему можно оставить открытой для сравнения языков в контексте этого вопроса. Сравнительный анализ - полезная вещь, особенно если новички зададутся вопросом отличия PascalABC.Net от других языков.</личное мнение>


#6

Да никто и не собирается её закрывать. Пусть сначала Админ выскажется.


#7

После снятия вопроса я обычно прошу модераторов закрыть тему. В данном случае думаю стоит сделать исключение.


#8

Да ничего подобного. Это работает:

type
  t1<T> = {static{} class
    
    class procedure p1 := writeln(typeof(T));
    
  end;

begin
  t1&<byte>.p1;
  t1&<word>.p1;
end.

Для шаблонных типов создаётся тип в котором T заменят на что то - когда в коде как то где то есть указание каким должен быть T. Для этого не обязательно создавать экземпляр.


#9

Ну, может под горячую руку и зря запретил. Только что такое статические генерик-классы и кому они нужны, вот в чем вопрос. Если кто найдет в стандартной библиотеке пример, я разрешу.


#10

@Sun_Serega, я впервые в жизни вижу пример со статическими шаблонными классами. Думаю, @ibond прав.


#11

А слабО статические абстрактные sealed generic-классы, наследуемые сами от себя, разрешить?


#12

Можно ещё раз? :smile:


#13

В стандартной библиотеке не знаю, я далеко не всюду копался, но вот, к примеру:

type
  UsedCounter<T> = {static{} class
    
    private class m_used: integer;
    
    public class procedure Inc :=
    m_used += 1;
    
    public class property Used: integer read m_used;
    
  end;

function f1<T>(o:T):object;
begin
  //ToDo что то делаем с "o"
  UsedCounter&<T>.Inc;
end;

begin
  loop 3 do f1(byte(0));
  loop 5 do f1('');
  
  writeln(UsedCounter&<byte>.Used);     // 3
  writeln(UsedCounter&<integer>.Used);  // 0
  writeln(UsedCounter&<string>.Used);   // 5
end.

Работает в основном как словарь, но более красиво и, вроде, быстро (надо провести ещё некоторые тесты).

Самое приятное - компилятор тут выполнит всю необходимую работу. (всм не надо создавать словарь, не надо писать typeof каждый раз, чтоб получить значение для определённого типа)


#14

Это на самом деле по-русски написано?


#15

Не надо перебарщивать. В этой записи есть несколько противоречий, как статичность+наследование.

А вот в шаблонных статичных классах таких противоречий нет, тут вопрос был только про нужность.


#17

Даже static-abstract/-sealed классы запрещены, чего уж усложнять? Тем более наследование для статических классов запрещено. И зачем наследоваться от самого себя? Какая польза?