Почему в генерике невозможно объявить влож. Enum и Variant?
От: FDSC Россия consp11.github.io блог
Дата: 23.08.11 18:56
Оценка:
Объявляю класс


public partial module WorkingClass[T] where T: Form, new()
    {
        i: int = 1;
        public I: System.Int32
        {
            get
            {
                i
            }
        }

        public mainWorking(): void
        {
            using (def testInstance = ThirdPartyLibrary.TestClass())
            {
                testInstance.open();
            }
        }

        public class InnerClass
        {
        }

        public event Event: int -> int
        {
            add
            {
                _ = value
            }
            remove
            {
                _ = value
            }
        }

        public variant SSS
        {
            | A {}
            | B {}
        }

        public enum ClassEnumeration { | verybad = -2 | bad | noRating | well | verywell}
    }



На два последних вложения ругается
error : enums cannot have generic type parameters
error : wrong number of type parameters to `SSS'

Если убрать генерик, то всё нормально работает
В чём проблема?
Re: Почему в генерике невозможно объявить влож. Enum и Varia
От: hardcase Пират http://nemerle.org
Дата: 23.08.11 19:03
Оценка: 1 (1)
Здравствуйте, FDSC, Вы писали:

FDS>В чём проблема?


Это баг (возможно дизайна). Параметры генериков протаскиваются через все вложенные типы. Т.е. тут получается что в энум приезжает неявный параметр T.
Я пока не знаю как исправить этот баг (не поломав все к чертям).
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Почему в генерике невозможно объявить влож. Enum и Varia
От: hardcase Пират http://nemerle.org
Дата: 23.08.11 19:06
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>В чём проблема?


В гугловском багтреке это один из самых старых багов. Поляки как-то по-своему понимали концепцию генериков дотнета.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Почему в генерике невозможно объявить влож. Enum и Va
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.08.11 19:50
Оценка:
Здравствуйте, hardcase, Вы писали:

FDS>>В чём проблема?


H>В гугловском багтреке это один из самых старых багов. Поляки как-то по-своему понимали концепцию генериков дотнета.


На мой взгляд, нормально понимаю. Если мы объявляем вложенный класс, то по шарповской иделогии он наследует внешний парамтр типов. Так почему с энумами должно быть по другому? Ну, а создать парметризованный энум в донете нельзя.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Почему в генерике невозможно объявить влож. Enum и Va
От: _FRED_ Черногория
Дата: 23.08.11 20:00
Оценка:
Здравствуйте, VladD2, Вы писали:

FDS>>>В чём проблема?

H>>В гугловском багтреке это один из самых старых багов. Поляки как-то по-своему понимали концепцию генериков дотнета.

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


А почему тогда в шарпе можно создать енам в дженерик-классе?

class Program
{
  static void Main() {
    var e1 = X<int>.E.V;
    var e2 = X<string>.E.V;
    var ee = e1 == (X<int>.E)e2;
  }
}

class X<Y>
{
    public enum E { V, }
}
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Почему в генерике невозможно объявить влож. Enum и Va
От: hardcase Пират http://nemerle.org
Дата: 23.08.11 20:01
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Хмм, действительно, значит я заблуждаюсь (я как-то ковырял этот баг да безрезультатно — опыта мало было). Вот IL для кода:

public class Outer<T>
{
  public class Inner { }
  
  public enum X { A ,B }
}


.class public auto ansi beforefieldinit Outer`1<T>
    extends [mscorlib]System.Object
{
    // Nested Types
    .class nested public auto ansi beforefieldinit Inner<T>
        extends [mscorlib]System.Object
    {
        // Methods
        .method public hidebysig specialname rtspecialname 
            instance void .ctor () cil managed 
        {
            // Method begins at RVA 0x2058
            // Code size 7 (0x7)
            .maxstack 8

            IL_0000: ldarg.0
            IL_0001: call instance void [mscorlib]System.Object::.ctor()
            IL_0006: ret
        } // end of method Inner::.ctor

    } // end of class Inner

    .class nested public auto ansi sealed X<T>
        extends [mscorlib]System.Enum
    {
        // Fields
        .field public specialname rtspecialname int32 value__
        .field public static literal valuetype Outer`1/X<!T> A = int32(0)
        .field public static literal valuetype Outer`1/X<!T> B = int32(1)

    } // end of class X


    // Methods
    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method Outer`1::.ctor

} // end of class Outer`1


Значит просто компилятор не различает внешние параметры типа и объявленные для enum-а.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Почему в генерике невозможно объявить влож. Enum и Varia
От: hardcase Пират http://nemerle.org
Дата: 23.08.11 20:06
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>В чём проблема?


Ок. я поправлю
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Почему в генерике невозможно объявить влож. Enum и Va
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.08.11 21:04
Оценка: -1 :)
Здравствуйте, _FRED_, Вы писали:

_FR>А почему тогда в шарпе можно создать енам в дженерик-классе?


_FR>
_FR>class Program
_FR>{
_FR>  static void Main() {
_FR>    var e1 = X<int>.E.V;
_FR>    var e2 = X<string>.E.V;
_FR>    var ee = e1 == (X<int>.E)e2;
_FR>  }
_FR>}

_FR>class X<Y>
_FR>{
_FR>    public enum E { V, }
_FR>}
_FR>


По дури, на мой взгляд. Смысла в этом нет ни грамма.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Почему в генерике невозможно объявить влож. Enum и Va
От: hardcase Пират http://nemerle.org
Дата: 23.08.11 21:07
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, FDSC, Вы писали:


FDS>>В чём проблема?


H>Ок. я поправлю


Это косяк в SRE. При попытке сгенерировать такой энум приезжает исключение из внутренностей System.Reflection.Emit.TypeBuilder:
C:\!Proj\nemerle>bin\Debug\net-3.5\Stage1\ncc.exe "C:\!Proj\nemerle\bin\p1.n" -out:C:\!Proj\nemerle\bin\p1.exe -t:exe
←[01;31merror←[0m: internal compiler error: got some unknown exception of type System.NotSupportedException: Указанный метод не поддерживает
ся.
   в System.Reflection.Emit.TypeBuilderInstantiation.IsSubclassOf(Type c)
   в System.Reflection.Emit.TypeBuilder.SetConstantValue(Module module, Int32 tk, Type destType, Object value)
   в System.Reflection.Emit.FieldBuilder.SetConstant(Object defaultValue)
   в Nemerle.Compiler.FieldBuilder.CreateEmitBuilder(TypeBuilder tb) в C:\!Proj\nemerle\ncc\generation\HierarchyEmitter.n:строка 1229


Такая фигня происходит при попытке установить значение в поле, отвечающее за отдельное значение перечисления.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Почему в генерике невозможно объявить влож. Enum и Va
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.08.11 21:09
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Такая фигня происходит при попытке установить значение в поле, отвечающее за отдельное значение перечисления.


Ты глянь, что компилятор шарпа генерирует в таких случаях. Не удивлюсь, если он создает энум без дженериков, а все байда с параметрами типов эмулируется.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Почему в генерике невозможно объявить влож. Enum и Va
От: hardcase Пират http://nemerle.org
Дата: 23.08.11 21:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, hardcase, Вы писали:


H>>Такая фигня происходит при попытке установить значение в поле, отвечающее за отдельное значение перечисления.


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


Он с генериком, посмотри внимательно на листинг, что я привел выше.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Почему в генерике невозможно объявить влож. Enum и Va
От: _FRED_ Черногория
Дата: 24.08.11 04:20
Оценка:
Здравствуйте, VladD2, Вы писали:

_FR>>А почему тогда в шарпе можно создать енам в дженерик-классе?


VD>По дури, на мой взгляд. Смысла в этом нет ни грамма.


Даже приватный не нужен, да? Суров ответ
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Почему в генерике невозможно объявить влож. Enum и Va
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.08.11 12:37
Оценка:
Здравствуйте, _FRED_, Вы писали:

VD>>По дури, на мой взгляд. Смысла в этом нет ни грамма.


_FR>Даже приватный не нужен, да? Суров ответ


Не понял.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Почему в генерике невозможно объявить влож. Enum и Va
От: hardcase Пират http://nemerle.org
Дата: 24.08.11 13:00
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, _FRED_, Вы писали:


VD>>>По дури, на мой взгляд. Смысла в этом нет ни грамма.


_FR>>Даже приватный не нужен, да? Суров ответ


VD>Не понял.


Приватный энум может быть полезен в контейнерных классах:
public class MyCollection<T>
{
  private enum ItemStates { Foo, Bar, Baz }
}

Где ItemStates используется исключительно для некоторой внутренней логики.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[7]: Почему в генерике невозможно объявить влож. Enum и Va
От: _FRED_ Черногория
Дата: 24.08.11 13:18
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>>>По дури, на мой взгляд. Смысла в этом нет ни грамма.

_FR>>Даже приватный не нужен, да? Суров ответ

VD>Не понял.


Внутри реализиции дженерик-класса

class X<Y>
{
  private enum E { V, }

  private E State { get; set; }

  public M() {
    switch(State) {
      // …
    }//switch
  }
}


Приватный енам может быть полезен внутри реализации любого класса, дженерик он или нет, и никакой "дури" в таких енамах нет.
Help will always be given at Hogwarts to those who ask for it.
Re[8]: Почему в генерике невозможно объявить влож. Enum и Va
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.08.11 14:10
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Приватный энум может быть полезен в контейнерных классах:

H>
H>public class MyCollection<T>
H>{
H>  private enum ItemStates { Foo, Bar, Baz }
H>}
H>

H>Где ItemStates используется исключительно для некоторой внутренней логики.

И что даст такая инкапсуляция? Что случится если этот enum будет internal?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Почему в генерике невозможно объявить влож. Enum и Va
От: FDSC Россия consp11.github.io блог
Дата: 24.08.11 14:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, hardcase, Вы писали:


H>>Приватный энум может быть полезен в контейнерных классах:

H>>
H>>public class MyCollection<T>
H>>{
H>>  private enum ItemStates { Foo, Bar, Baz }
H>>}
H>>

H>>Где ItemStates используется исключительно для некоторой внутренней логики.

VD>И что даст такая инкапсуляция? Что случится если этот enum будет internal?


А, собственно, что в этом плохого? Мы просто хотим структурировать программу, вводя некоторый вложенный Enum, как и в других классах. Что даст инкапсуляция перечисления в нешаблонный класс?
Re[9]: Почему в генерике невозможно объявить влож. Enum и Va
От: catbert  
Дата: 24.08.11 14:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>И что даст такая инкапсуляция? Что случится если этот enum будет internal?


То, что данный enum можно спрятать от классов внутри сборки.
Re[5]: Почему в генерике невозможно объявить влож. Enum и Va
От: IT Россия linq2db.com
Дата: 24.08.11 15:11
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>По дури, на мой взгляд. Смысла в этом нет ни грамма.


А почему это в Nemerle сделать нельзя?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Почему в генерике невозможно объявить влож. Enum и Va
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.08.11 16:20
Оценка: :)
Здравствуйте, IT, Вы писали:

VD>>По дури, на мой взгляд. Смысла в этом нет ни грамма.


IT>А почему это в Nemerle сделать нельзя?


SRE не позволяет. Да и не нужно никому.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.