【问题标题】:Why does this generic method require T to have a public, parameterless constructor?为什么这个泛型方法要求 T 有一个公共的、无参数的构造函数?
【发布时间】:2023-03-09 13:25:02
【问题描述】:
public void Getrecords(ref IList iList,T dataItem) 
{ 
  iList = Populate.GetList<dataItem>() // GetListis defined as GetList<T>
}

dataItem 可以是我的订单对象或用户对象,这将在运行时决定。上面的内容不起作用,因为它给了我这个错误 类型“T”必须具有公共无参数构造函数,才能将其用作泛型类型中的参数“T”

【问题讨论】:

  • 你的问题很模糊,很难理解......你想做什么?
  • 为什么这个人只是问一个问题就被否决了?
  • 你能澄清一下 dataItem 在这里做什么吗?它不能用作泛型类型参数(T 可以)。那么它有什么作用呢?
  • 重新回答(在我的帖子中)- 我发布的两种情况中的任何一种都有帮助吗?

标签: c# generics


【解决方案1】:
public void GetRecords<T>(ref IList<T> iList, T dataitem)
{
}

你还在寻找什么?

修改后的问题:

 iList = Populate.GetList<dataItem>() 

“数据项”是一个变量。你想在那里指定一个类型:

 iList = Populate.GetList<T>() 

类型“T”必须有一个公共 无参数构造函数 将其用作泛型中的参数“T” 输入 GetList:new()

这就是说,当你定义 Populate.GetList() 时,你是这样声明的:

IList<T> GetList<T>() where T: new() 
{...}

这告诉编译器 GetList 只能使用具有公共无参数构造函数的类型。在 GetRecords 中使用 T 创建一个 GetList 方法(这里的 T 指的是不同的类型),你必须对其进行相同的限制:

public void GetRecords<T>(ref IList<T> iList, T dataitem) where T: new() 
{
   iList = Populate.GetList<T>();
}

【讨论】:

    【解决方案2】:

    您修改后的问题将 dataItem 作为类型 T 的对象传递,然后尝试将其用作 GetList() 的类型参数。也许您传递 dataItem 只是作为指定 T 的一种方式?

    如果是这样,你可能想要这样的东西:

    public IList<T> GetRecords<T>() {
      return Populate.GetList<T>();
    }
    

    然后你这样称呼它:

    IList<int> result = GetRecords<int>();
    

    【讨论】:

    • 我试过了,我得到了这个类型'T'必须有一个公共的无参数构造函数才能将它用作泛型类型GetList中的参数'T':new()跨度>
    • 如果需要能够新建,指定T:object
    • 或者,您也可以使用 default(T) 创建一个新实例。
    • 其中 T : new() 是编译器想要的
    • 我一度认为这也是他想要的,然后我意识到他可能已经有一个他想要用来确定方法的类型参数的某种类型的对象。即便如此,这仍然可能是正确的方法。只需使用 MyDataItem.GetType() 作为类型参数。
    【解决方案3】:

    要求公共、无参数构造函数的问题只能是因为 Populate.GetList 需要它 - 即具有“T : new()”约束。要解决此问题,只需在您的方法中添加相同的约束即可。

    实际上,我怀疑ref 在这里是一个好策略。在推送中,out 可能会这样做(因为您没有读取该值),但一个更简单(并且更值得期待)的选项是返回值:

    public IList<T> GetRecords<T>(T dataItem) where T : new()
    {  // MG: what does dataItem do here???
      return Populate.GetList<T>();
    }
    

    当然,此时调用者还不如直接调用Populate.GetList

    我怀疑您也可以删除 dataItem ......但问题并不完全清楚。

    如果您不希望它是通用的(并且 dataItem 是模板对象),那么您可以通过MakeGenericMethod 执行此操作:

    public static IList GetRecords(object dataItem) 
    {
        Type type = dataItem.GetType();
        return (IList) typeof(Populate).GetMethod("GetList")
            .MakeGenericMethod(type).Invoke(null,null);
    }
    

    【讨论】:

    • MG:如果我有一个订单对象,那么列表将是订单对象的集合,它可以帮助我避免构建我自己的强类型集合,继承自集合基础并循环遍历数据集并构建集合,所以我可以传递自定义集合而不是数据集
    【解决方案4】:

    您可以将 Generic 与 一起使用,这将在运行时接受您想要的类型。

    【讨论】:

      【解决方案5】:
      Getrecords<T> ...
      

      这应该包含您需要的任何更详细的信息。 http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx

      【讨论】:

        猜你喜欢
        • 2011-05-08
        • 1970-01-01
        • 2020-03-22
        • 1970-01-01
        • 2011-10-27
        • 2012-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多