Приведенный ниже код успешно компилируется, но при запуске получаем:
TypeLoadException: Could not load type 'D'
Вот код.
struct A<T> { }
struct D
{
public A<D> ar;
}
class Program
{
static void Main()
{
System.Console.WriteLine(new D().ar); ;
}
}
С одной стороны D используется в параметре типа структуры вложенной D, т.е. имеем рекурсивное определение структуры.
Но с другой ведь параметр типа не использован нигде в A или может быть использован для задания параметра типа у ссылочного типа (т.е. не приводит к проблеме рекурсии).
Короче, вопрос: где баг, в компиляторе (который не сообщает об ошибке) или в рантайме, который вылетает не по делу?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Но с другой ведь параметр типа не использован нигде в A
Это он пока не использован. Каким бы ни должно быть поведение у компилятора/рантайма для типа D, оно не долэно изменяться при добавлении использования параметра T в структуре A<T>.
Здравствуйте, VladD2, Вы писали:
VD>Короче, вопрос: где баг, в компиляторе (который не сообщает об ошибке) или в рантайме, который вылетает не по делу?
Рантайм по делу, компилятор пропустил.
Пруфлинков не найду, но точно видел обсуждение чего-то похожего лет так 7 назад.
Здравствуйте, Qbit86, Вы писали:
VD>>Но с другой ведь параметр типа не использован нигде в A
Q>Это он пока не использован. Каким бы ни должно быть поведение у компилятора/рантайма для типа D, оно не долэно изменяться при добавлении использования параметра T в структуре A<T>.
Вот когда будет использоваться тогда и надо жаловаться. С таким подходом можно дойти до того, что в статическом конструкторе исключения кидать нельзя.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, TK, Вы писали:
TK>Вот когда будет использоваться тогда и надо жаловаться. С таким подходом можно дойти до того, что в статическом конструкторе исключения кидать нельзя.
Типы могут быть разнесены. Базовый тип в одной сборке первого автора, наследник — в другой сборке второго автора. Было бы странно, что у второго автора что-то радикально изменится (неважно, в хорошую или плохую сторону) в поведении компилятора или рантайма только от того, что автор базовой сборки добавил какой-нибудь приватный метод с типом T в сигнатуре, или приватное поле типа T.
Здравствуйте, Qbit86, Вы писали:
Q>Это он пока не использован. Каким бы ни должно быть поведение у компилятора/рантайма для типа D, оно не долэно изменяться при добавлении использования параметра T в структуре A<T>.
Это ты не подумав сказал. Представь себе, что вместо а ImmutableArray<T> где T используется исключительно для задания типа элемента массива. Какие проблемы?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinix, Вы писали:
VD>>Короче, вопрос: где баг, в компиляторе (который не сообщает об ошибке) или в рантайме, который вылетает не по делу? S>Рантайм по делу, компилятор пропустил.
А я склоняюсь к обратному. Рантайм должен гавкать, если я этот параметр типа использую для определения поля в той структуре. А для других типов — это проблем не создаст.
Такое ограничение закрывает возможность использовать ImmutableArray<T> в структурах типа T. И это ооочень неприятно. Немерл, кстати, тоже пропустил это дело, но вылетел при загрузки сборки через рефлексию (в другом проекта).
S>Пруфлинков не найду, но точно видел обсуждение чего-то похожего лет так 7 назад.
Значит бага весит 7 лет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>А я склоняюсь к обратному. Рантайм должен гавкать, если я этот параметр типа использую для определения поля в той структуре. А для других типов — это проблем не создаст.
Логично, главный довод против — менять CLI standard. Вот тут проблема, т.к. даже куда более полезные вещи типа продвинутых ограничений для генериков туда пропихнуть не получается, вот уже 11 лет как
VD>Такое ограничение закрывает возможность использовать ImmutableArray<T> в структурах типа T. И это ооочень неприятно. Немерл, кстати, тоже пропустил это дело, но вылетел при загрузки сборки через рефлексию (в другом проекта).
Здравствуйте, Sinix, Вы писали:
S>Логично, главный довод против — менять CLI standard.
А этот случай в нем описан? Может это баг в рантайме. Кто знает?
S>Вот тут проблема, т.к. даже куда более полезные вещи типа продвинутых ограничений для генериков туда пропихнуть не получается, вот уже 11 лет как
Я бы не сказал, что это не серьезная вещь. Она ограничивает использование структур в качестве рэйдонли-обертки, как в случае ImmutableArray<T>.
S>А, известный баг. Вот ещё на эту тему.
Тем более. Значит все же косяк в рантайме. Там то уж точно все хокейно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Qbit86, Вы писали:
TK>>Вот когда будет использоваться тогда и надо жаловаться. С таким подходом можно дойти до того, что в статическом конструкторе исключения кидать нельзя.
Q>Типы могут быть разнесены. Базовый тип в одной сборке первого автора, наследник — в другой сборке второго автора. Было бы странно, что у второго автора что-то радикально изменится (неважно, в хорошую или плохую сторону) в поведении компилятора или рантайма только от того, что автор базовой сборки добавил какой-нибудь приватный метод с типом T в сигнатуре, или приватное поле типа T.
Это ожидаемое поведение. Автор базовой сборки может кинуть исключение в конструкторе типа или вообще удалить свой left-pad из нугета.
Компилятор может максимум что warning выдать.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.