【问题标题】:Cannot implicitly convert type void to List无法将类型 void 隐式转换为 List
【发布时间】:2018-02-08 08:03:48
【问题描述】:

我有以下类结构:

class Child
{
    public List<ParentData> ParentData { get; set; }
}

class ParentData
{
    public string FatherName {get;set;}
    public string MotherName {get;set;}
    public List<GrandParentData> GrandParentData{ get; set; }
}

class GrandParentData
{
    public string GrandFatherName {get;set;}
    public string GrandMotherName {get;set;}
}

当我尝试填写此内容时:

foreach (var item in res)
{
    obj.StoryData.Add(
        new StoryData
        {
            FatherName = item.FatherName,
            MotherName = item.Description,                                                                        
            GrandParentData = new List<GrandParentData().Add(
                new GrandParentData 
                { 
                    GrandFatherName = "",
                    GrandMotherName = ""
                }
            );
        }                            
    );
}

当我尝试将数据添加到 GrandParentList 列表时出现错误:

无法将类型 void 隐式转换为 List

我需要改变我的班级结构吗?我应该对我的代码进行哪些编辑?

【问题讨论】:

  • 请在格式化您的代码方面付出更多努力——您的第二个 sn-p 目前真的很难阅读。 (而且你的类中的两个空格缩进远非惯用。)

标签: c# .net


【解决方案1】:

所以这部分是问题所在:

GrandParentData=new List<GrandParentData().Add(
    new GrandParentData { GrandFatherName = "",GrandMotherName =""});

这里有三个问题:

  • 您没有关闭类型参数
  • 尽管它是对象初始化程序的一部分,但您在末尾有一个分号
  • 您正在调用 Add 方法,该方法返回 void - 因此出现编译时错误

作为对最后一部分的进一步解释,忽略您在对象初始化器中的事实,您的代码相当于尝试编写如下内容:

List<int> list = new List<int>().Add(1);

这是无效的,因为new List&lt;int&gt;().Add(1) 不返回任何内容。要像这样显式使用Add,您需要单独声明变量:

List<int> list = new List<int>();
list.Add(1);

当然,这在对象初始化器中不起作用,因为您需要提供一个表达式来设置属性。

解决方案是使用 集合初始化器。在我们的简单案例中:

List<int> list = new List<int> { 1 };

在您更复杂的情况下,您可以这样做:

GrandParentData = new List<GrandParentData>
{ 
    new GrandParentData { GrandFatherName = "", GrandMotherName = "" }
}

或者,您可以将 GrandParentData 更改为只读属性,但已将其初始化,如下所示:

public List<GrandParentData> GrandParentData { get; } =
    new  List<GrandParentData>();

那么你可以写:

GrandParentData =
{ 
    new GrandParentData { GrandFatherName = "", GrandMotherName = "" }
}

...并且新的GrandParentData 将添加到现有集合中。

【讨论】:

    【解决方案2】:

    您不能创建一个新列表,然后以这种方式(分配值)调用Add

    • 代替:

      GrandParentData = new List<GrandParentData>().Add(...)
      
    • 写入(使用集合初始化语法):

      GrandParentData = new List<GrandParentData> { new GrandParentData { ... } }
      

    具体错误的原因是 Add 是一个 void 方法,因此当您尝试将结果分配给属性时,您会收到错误。

    检查以下代码,第一行正常,但第二行出错:

    new List<string>().Add("text");
    var list = new List<string>().Add("text");
    

    虽然第一行确实有效并且没有给出错误,但它现在可以理解,因为您没有引用该集合,初始化列表将由 GC 收集

    【讨论】:

      【解决方案3】:

      您正在尝试将Add 方法的结果(void)分配给变量。这是不可能的。 void 不能分配给变量。

      collection initializers 来救援:

      GrandParentData = new List<GrandParentData()
                        { new GrandParentData { GrandFatherName = "",GrandMotherName =""}
                        }
      

      【讨论】:

        【解决方案4】:

        问题的来源是这段代码:

        GrandParentData=new List<GrandParentData().Add(
        new GrandParentData { GrandFatherName = "",GrandMotherName =""}
        

        为什么?

        GrandParentDataList&lt;GrandParentData&gt; 类型,List&lt;GrandParentData&gt;.Add 方法返回 void,所以它只是说你不能将 List&lt;GrandParentData&gt; 映射到 void 返回,这是公平的。以下是List&lt;T&gt;.Add的实现

         public void Add(T item) {
                    if (_size == _items.Length) EnsureCapacity(_size + 1);
                    _items[_size++] = item;
                    _version++;
                }
        

        查看here

        解决办法是:

        正如上面其他答案中列出的那样,您在创建列表时添加对象,实际上您可以简单地这样做:

        GrandParentData = new List<GrandParentData() { new GrandParentData()}
        

        并在构造函数中分配默认值如下:

        class GrandParentData
        {
            public string GrandFatherName {get;set;}
            public string GrandMotherName {get;set;}
        
            public GrandParentData()
            {
               GrandFatherName = "";
               GrandMotherName = "";
        
            }
        }
        

        另一方面,与模型设计有关的另一个令人惊讶的点是,有一个名为 GrandParentData 的模型,而您有一个 public List&lt;GrandParentData&gt; GrandParentData{ get; set; },这通常令人困惑,最好使用后缀来表明它是一个集合

        【讨论】:

          猜你喜欢
          • 2013-02-22
          • 1970-01-01
          • 1970-01-01
          • 2014-04-14
          • 2016-02-17
          • 2015-04-26
          • 2015-03-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多