Я начал этот вопрос с множества предыстории рассматриваемых типов; интерфейсы и обоснование архитектуры.
Затем я понял - «Это ТАК - делайте это простым и переходите к сути».
Итак, начнем.
У меня есть такой класс:
public class AGenericType<T> : AGenericTypeBase
{
T Value { get; set; }
}
В таком случае .Net, конечно, позволяет мне сделать это:
AGenericType<AGenericType<int>> v;
Однако в контексте использования AGenericType
делать это так же, как и ерунда делать это:
Nullable<Nullable<double>> v;
Я хочу ограничить этот универсальный тип, чтобы было невозможно создать такой экземпляр или даже объявить ссылку на тип, когда он T
является производным из AGenericTypeBase
- предпочтительно во время компиляции.
Интересно то, что Nullable
, который я привожу здесь , действительно генерирует ошибку компилятора. Но я не могу понять, как Nullable
ограничивает T
не- Nullable
типами - поскольку Nullable
- это структура, и единственное общее ограничение, которое я могу найти (даже в IL, который часто дает секреты компилятора, например, с делегатами), это , где T: struct
. Итак, я думаю, что это должно быть хакерство компилятора ( EDIT: см. Ответ @Daniel Hilgarth + комментарии ниже, чтобы немного изучить это ). Взлом компилятора, который я, конечно, не могу повторить!
В моем собственном сценарии IL и C # не допускают ограничение отрицательного утверждения, подобное этому:
public class AGenericType<T> : where !T:AGenericTypeBase
(обратите внимание на '!' в ограничении)
Но какую альтернативу я могу использовать?
Я подумал о двух:
1) Исключение времени выполнения, созданное в конструкторе AGenericType
:
public AGenericType(){
if(typeof(AGenericBase).IsAssignableFrom(typeof(T)))
throw new InvalidOperationException();
}
Однако это на самом деле не отражает природы ошибки - потому что проблема заключается в общем параметре и, следовательно, во всем типе; не только этот экземпляр.
2) Вместо этого то же исключение времени выполнения, но сгенерированное в статическом инициализаторе для AGenericType
:
static AGenericType(){
if(typeof(AGenericBase).IsAssignableFrom(typeof(T)))
throw new InvalidOperationException();
}
Но затем я столкнулся с проблемой, что это исключение будет заключено в исключение TypeInitializationException
и потенциально может вызвать путаницу (по моему опыту разработчики, которые фактически читают всю иерархию исключений, тонки на земле).
Для меня это явный случай для 'отрицательное утверждение'
svn cp -m 'Создание тестовой ветки' svn: // svnrepo / hellosite svn: // svnrepo / hellosite2
Итак, для перехода мне нужно каждый раз указывать полный URL удаленного репозитория. Но:
Так почему же я должен вводить полные URL-адреса каждый раз? !! Или я что-то упускаю?
Есть ли какой-то ярлык, который позволяет ссылаться на текущий удаленный репозиторий? Что-то типа
svn cp -m 'Создание тестовой ветви' // hellosite // hellosite2