简体   繁体   English

泛型:何时使用new()作为类型参数的约束?

[英]Generics: When to use new() as a constraint of Type Parameters?

The type argument must have a public parameterless constructor. type参数必须具有公共无参数构造函数。 When used together with other constraints, the new() constraint must be specified last. 与其他约束一起使用时,必须最后指定new()约束。

Can you guys give me a sample scenario when this constraint is needed? 当需要这种约束时,你能给我一个示例场景吗?

This is essentially what the new() constraint boils down to: 这基本上是new()约束归结为:

class Factory<T> where T : new()
{
    public T Create()
    {
        return new T();
        //     ^^^^^^^
        //     this requires the new() type constraint.
    }
}

Now, you're not allowed to pass arguments to the constructor. 现在,您不允许将参数传递给构造函数。 If you nevertheless want to initialize the newed object, you could achieve this eg by introducing a further constraint: 如果你想初始化新的对象,你可以通过引入另一个约束来实现这个目的:

interface ILikeBananas
{
    double GreenBananaPreferenceFactor { get; set; }
}

class Factory<T> where T : ILikeBananas, new()
{
    public T Create(double greenBananaPreferenceFactor)
    {
        ILikeBananas result = new T();
        result.GreenBananaPreferenceFactor = greenBananaPreferenceFactor;

        return (T)result;
        //     ^^^^^^^^^
        //     freely converting between ILikeBananas and T is permitted
        //     only because of the interface constraint.
    }
}

Note that another way of instantiating an object is via Activator.CreateInstance , which gives you some more freedom, such as passing arguments directly to a constructor. 请注意,实例化对象的另一种方法是通过Activator.CreateInstance ,它可以为您提供更多自由,例如将参数直接传递给构造函数。

Activator.CreateInstance does not strictly require the new() constraint; Activator.CreateInstance并不严格要求new()约束; however, the type being instantiated still needs to provide a suitable constructor. 但是,实例化的类型仍然需要提供合适的构造函数。

It's seldom needed in the sense of being the only way of accomplishing something. 从成为某种事物的唯一方式来看,它很少需要 But sometimes it's the easiest way to do something. 但有时它是最简单的做事方式。

For example let's say you're writing an object pool. 例如,假设你正在编写一个对象池。 When someone wants to take an object from the pool, it either returns an existing object or simply creates a new one if none is available. 当有人想要从池中获取一个对象时,它会返回一个现有对象,或者只是在没有可用的情况下创建一个新对象。 You could add the where T : new() constraint to allow yourself to simply write return new T(); 您可以添加where T : new()约束以允许自己简单地写return new T(); .

The constraint isn't needed here, as you could've accomplished the same thing by taking a Func<T> in the pool's constructor and using that. 这里不需要约束,因为你可以通过在池的构造函数中使用Func<T>并使用它来完成同样的事情。 Arguably, this method is in fact better, as it's more flexible. 可以说,这种方法实际上更好,因为它更灵活。 But again, new T() is just nice and easy. 但同样, new T()也很简单。

I'll just drop in a simple example. 我只想举一个简单的例子。 I've created a method: 我创建了一个方法:

public T GetFromXml<T>(string xml)
    where T: class, new()
{
    if (String.IsNullOrEmpty(xml))
    {
        return new T();
    }
    return xml.AsObjectFromXml<T>();
}

And use it like this: 并像这样使用它:

Phones = GetFromXml<List<PhoneData>>(source.Phones);

Because I prefer empty collections over null values. 因为我更喜欢空集合而不是空值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM