Есть ли способ принудительно установить / ограничить типы, передаваемые примитивам? (bool, int, string и т. Д.)
Теперь я знаю, что вы можете ограничить универсальный параметр типа реализацией типа или интерфейса с помощью предложения , где . Тем не менее, это не соответствует требованиям для примитивов (AFAIK), потому что они не все имеют общий язык (кроме объект , прежде чем кто-то скажет!: P).
Итак, мои нынешние мысли - просто стиснуть зубы и сделать большой оператор switch и выбросить ArgumentException при ошибке ..
РЕДАКТИРОВАТЬ 1:
Просто чтобы уточнить:
Определение кода должно быть таким:
public class MyClass<GenericType> ....
И экземпляр:
MyClass<bool> = new MyClass<bool>(); // Legal
MyClass<string> = new MyClass<string>(); // Legal
MyClass<DataSet> = new MyClass<DataSet>(); // Illegal
MyClass<RobsFunkyHat> = new MyClass<RobsFunkyHat>(); // Illegal (but looks awesome!)
РЕДАКТИРОВАТЬ 2
@ Jon Limjap - Хороший вопрос, и кое-что, что я уже рассматривал ... Я уверен, что есть универсальный метод, который можно использовать для определения, является ли тип значением или ссылочным типом.
Это может быть полезно для мгновенного удаления множества объектов, с которыми я не хочу иметь дело (но тогда вам нужно беспокоиться об используемых структурах, таких как Размер ). Интересной проблемы нет? :)
Вот оно:
where T : struct
Взято из MSDN .
Мне любопытно. Может ли это быть сделано в .NET 3.x с использованием методов расширения? Создайте интерфейс и реализуйте интерфейс в методах расширения (которые, вероятно, будут чище, чем немного жирный переключатель). Кроме того, если вам затем потребуется расширить на любые легковесные пользовательские типы, они также могут реализовать тот же интерфейс без изменений в базовом коде.
Что вы, ребята, думаете?
Печальные новости - я работаю в Framework 2 !! : D
РЕДАКТИРОВАТЬ 3
Это было так просто после Jon Limjaps Pointer .. Так просто, что я почти хочу плакать, но это здорово, потому что код работает как шарм!
Итак, вот что я сделал (вы будете смеяться!):
Код, добавленный к универсальному классу
bool TypeValid()
{
// Get the TypeCode from the Primitive Type
TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));
// All of the TypeCode Enumeration refer Primitive Types
// with the exception of Object and Empty (Null).
// Since I am willing to allow Null Types (at this time)
// all we need to check for is Object!
switch (code)
{
case TypeCode.Object:
return false;
default:
return true;
}
}
Затем небольшой служебный метод для проверки типа и выдачи исключения,
private void EnforcePrimitiveType()
{
if (!TypeValid())
throw new InvalidOperationException(
"Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name +
"' - this Class is Designed to Work with Primitive Data Types Only.");
}
Все, что затем необходимо сделать, - это вызвать EnforcePrimitiveType () в конструкторах классов. Работа выполнена! : -)
Единственный недостаток, он генерирует исключение только во время выполнения (очевидно), а не во время разработки. Но это не страшно и может быть подхвачено такими утилитами, как FxCop (чего мы не делаем использовать на работе).
Особая благодарность Джону Лимджапу за это!