Подтвердить что ты не робот

Больше пустяков, чем действительно важно: почему нет нового() ограничения на Activator.CreateInstance <T>()?

Я думаю, что есть люди, которые могут ответить на этот вопрос, это вопрос из любопытства:

Общий CreateInstance метод из System.Activator, введенный в .NET v2, не имеет ограничений типа для общего аргумента, но требует конструктора по умолчанию для активированного типа, в противном случае создается MissingMethodException. Для меня кажется очевидным, что этот метод должен иметь ограничение типа, например

Activator.CreateInstance<T>() where T : new() {
   ...
}

Просто упущение или какой-то анекдот, скрывающийся здесь?

Обновление

Как указано, компилятор не позволяет вам писать

private T Create<T>() where T : struct, new()
error CS0451: The 'new()' constraint cannot be used with the 'struct' constraint

Однако, см. комментарии, структура struct может использоваться как аргумент типа для общего метода, определяющего ограничение new(). При этом обстоятельстве данный ответ кажется единственной действительной причиной, чтобы не ограничивать метод...

Спасибо, что посмотрели!

4b9b3361

Ответ 1

Я мог ошибаться, но главное преимущество, которое я вижу, это то, что он позволяет вам сделать что-то вроде этого:

// Simple illustration only, not claiming this is awesome code!
class Cache<T>
{
    private T _instance;

    public T Get()
    {
        if (_instance == null)
        {
            _instance = Create();
        }

        return _instance;
    }

    protected virtual T Create()
    {
        return Activator.CreateInstance<T>();
    }
}

Обратите внимание, что если Activator.CreateInstance<T> имеет ограничение where T : new(), то вышеприведенный класс Cache<T> также нуждается в этом ограничении, которое было бы чрезмерно ограничительным, поскольку Create является виртуальным методом, и некоторый производный класс может захотеть использовать другое средство создания экземпляра, например вызов внутреннего конструктора типа или использование метода статического построителя.