如果BaseFruit有一个构造函数接受int权重,我可以实例化一个水果在一个泛型方法像这样?

public void AddFruit<T>()where T: BaseFruit{
    BaseFruit fruit = new T(weight); /*new Apple(150);*/
    fruit.Enlist(fruitManager);
}

注释后面添加了一个示例。似乎只有给BaseFruit一个无参数的构造函数,然后通过成员变量填充所有内容,才能做到这一点。在我的实际代码中(不是关于水果),这是相当不切实际的。

- update - 所以它似乎不能用任何约束条件来解决。从答案中可以得出三个备选方案:

工厂模式 反射 激活剂

我倾向于认为反射是最不干净的一种,但我无法在另外两种之间做出决定。


当前回答

是的,改变你的位置:

where T:BaseFruit, new()

但是,这只适用于无参数构造函数。您必须使用其他方法来设置属性(设置属性本身或类似的东西)。

其他回答

作为user1471935建议的补充:

要使用带有一个或多个参数的构造函数实例化泛型类,现在可以使用Activator类。

T instance = Activator.CreateInstance(typeof(T), new object[] {...}) 

对象列表是您想要提供的参数。微软表示:

调用CreateInstance(…]使用最匹配指定参数的构造函数创建指定类型的实例。

还有一个CreateInstance的通用版本(CreateInstance<T>()),但该版本也不允许提供构造函数参数。

最简单的解决方案 Activator.CreateInstance T < > ()

可以使用如下命令:

 T instance = (T)typeof(T).GetConstructor(new Type[0]).Invoke(new object[0]);

一定要看到下面的内容 参考。

正如Jon指出的,这是约束非参数构造函数的生命。然而,另一种解决方案是使用工厂模式。这很容易受到约束

interface IFruitFactory<T> where T : BaseFruit {
  T Create(int weight);
}

public void AddFruit<T>( IFruitFactory<T> factory ) where T: BaseFruit {    
  BaseFruit fruit = factory.Create(weight); /*new Apple(150);*/    
  fruit.Enlist(fruitManager);
}

还有一种选择是使用函数方法。传入一个工厂方法。

public void AddFruit<T>(Func<int,T> factoryDel) where T : BaseFruit { 
  BaseFruit fruit = factoryDel(weight); /* new Apple(150); */
  fruit.Enlist(fruitManager);
}

你不能使用任何参数化构造函数。如果有“where T: new()”约束,则可以使用无参数构造函数。

这很痛苦,但生活就是这样。

这是我想用“静态接口”解决的问题之一。然后可以约束T以包含静态方法、操作符和构造函数,然后调用它们。