我试图在添加到列表时通过其构造函数创建一个T类型的新对象。

我得到一个编译错误:错误消息是:

'T':创建变量实例时不能提供参数

但是我的类确实有构造函数参数!我该怎么做呢?

public static string GetAllItems<T>(...) where T : new()
{
   ...
   List<T> tabListItems = new List<T>();
   foreach (ListItem listItem in listCollection) 
   {
       tabListItems.Add(new T(listItem)); // error here.
   } 
   ...
}

当前回答

对象初始化器

如果你的带形参的构造函数除了设置属性之外没有做任何事情,你可以在c# 3中使用对象初始化器而不是调用构造函数来做这件事(这是不可能的,正如前面提到的):

public static string GetAllItems<T>(...) where T : new()
{
   ...
   List<T> tabListItems = new List<T>();
   foreach (ListItem listItem in listCollection) 
   {
       tabListItems.Add(new T() { YourPropertyName = listItem } ); // Now using object initializer
   } 
   ...
}

使用它,您也可以将任何构造函数逻辑放在默认(空)构造函数中。

Activator.CreateInstance ()

或者,你可以像这样调用Activator.CreateInstance():

public static string GetAllItems<T>(...) where T : new()
{
   ...
   List<T> tabListItems = new List<T>();
   foreach (ListItem listItem in listCollection) 
   {
        object[] args = new object[] { listItem };
        tabListItems.Add((T)Activator.CreateInstance(typeof(T), args)); // Now using Activator.CreateInstance
   } 
   ...
}

注意Activator。CreateInstance可能有一些性能开销,如果执行速度是最优先考虑的,并且另一个选项对您来说是可维护的,那么您可能希望避免这些开销。

其他回答

我发现我得到了一个错误“在创建类型参数T的实例时不能提供参数”,所以我需要这样做:

var x = Activator.CreateInstance(typeof(T), args) as T;

您需要在此处添加T: new(),以让编译器知道T保证提供默认构造函数。

public static string GetAllItems<T>(...) where T: new()

如果您所需要的只是从ListItem转换到类型T,则可以在T类中作为转换操作符实现此转换。

public class T
{
    public static implicit operator T(ListItem listItem) => /* ... */;
}

public static string GetAllItems(...)
{
    ...
    List<T> tabListItems = new List<T>();
    foreach (ListItem listItem in listCollection) 
    {
        tabListItems.Add(listItem);
    } 
    ...
}

对象初始化器

如果你的带形参的构造函数除了设置属性之外没有做任何事情,你可以在c# 3中使用对象初始化器而不是调用构造函数来做这件事(这是不可能的,正如前面提到的):

public static string GetAllItems<T>(...) where T : new()
{
   ...
   List<T> tabListItems = new List<T>();
   foreach (ListItem listItem in listCollection) 
   {
       tabListItems.Add(new T() { YourPropertyName = listItem } ); // Now using object initializer
   } 
   ...
}

使用它,您也可以将任何构造函数逻辑放在默认(空)构造函数中。

Activator.CreateInstance ()

或者,你可以像这样调用Activator.CreateInstance():

public static string GetAllItems<T>(...) where T : new()
{
   ...
   List<T> tabListItems = new List<T>();
   foreach (ListItem listItem in listCollection) 
   {
        object[] args = new object[] { listItem };
        tabListItems.Add((T)Activator.CreateInstance(typeof(T), args)); // Now using Activator.CreateInstance
   } 
   ...
}

注意Activator。CreateInstance可能有一些性能开销,如果执行速度是最优先考虑的,并且另一个选项对您来说是可维护的,那么您可能希望避免这些开销。

我认为必须用where语句约束T,以只允许具有新构造函数的对象。

现在它接受任何东西,包括没有它的对象。