【问题标题】:c# Merging lists with double propertiesc# 合并具有双重属性的列表
【发布时间】:2013-12-11 19:39:55
【问题描述】:

我在网上搜索了这段代码,合并了几个列表并返回一个。如果所有属性都是字符串,则代码有效,但如果某些属性是双精度的,我会收到错误消息。这个错误是“操作员'??'不能应用于“双”和“双”类型的操作数”。任何帮助是极大的赞赏。谢谢

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {

            List<Project> lst1; List<Project> lst2; List<Project> lst3;
            lst1 = new List<Project> 
            {
                new Project { ProjectId = 1, ProjectName = "P1" },
                new Project { ProjectId = 2, ProjectName = "P2" },
                new Project { ProjectId = 3, ProjectName = "P3" }
            };
                    lst2 = new List<Project>
            {
                new Project { ProjectId = 1, CustomerNum = 1},
                new Project { ProjectId = 2, CustomerNum = 2},
                new Project { ProjectId = 3, CustomerNum = 3}
            };
                    lst3 = new List<Project>
            {
                new Project { ProjectId = 1, Address = 10},
                new Project { ProjectId = 2, Address = 20},
                new Project { ProjectId = 3, Address = 30}
            };

                    List<Project> lst = lst1.Union(lst2).Union(lst3).ToLookup(x => x.ProjectId).Select(x => new Project()
                    {
                        ProjectId = x.Key,
                        ProjectName = x.Select(y => y.ProjectName).Aggregate((z1, z2) => z1 ?? z2),
                        CustomerNum = x.Select(y => y.CustomerNum).Aggregate((z1, z2) => z1 ?? z2),
                        Address = x.Select(y => y.Address).Aggregate((z1, z2) => z1 ?? z2)
                    }).ToList();


            foreach (var item in lst)
            {
                Console.WriteLine("{0}, {1}, {2}, {3}", item.ProjectId, item.ProjectName, item.CustomerNum, item.Address);

            }     
        }
    }

    public class Project
    {
        public int ProjectId { get; set; }
        public string ProjectName { get; set; }
        public double CustomerNum { get; set; }
        public double Address { get; set; }
    }
}

【问题讨论】:

    标签: c# list merge union


    【解决方案1】:

    Null 合并不适用于左侧的不可空类型 (double)

    来自this MSDN article

    ??运算符称为 null-coalescing 运算符,用于为 可空值类型或引用类型

    定义默认值

    因此,您可以使用double? (Nullable&lt;double&gt;),这样就可以了。但是,正如所写,左侧总是有一个值,因此你的问题。 Alternatively, you could check if the type is a value type?

    【讨论】:

    • 随机投反对票,如果还在的话,你能解释一下投反对票吗?
    【解决方案2】:

    如果您希望您的代码执行与其他类型相同的操作,您可以执行以下操作

    CustomerNum = x.Select(y => y.CustomerNum).Aggregate((z1, z2) => z1)
    

    【讨论】:

    • 由于 z1 是双精度数,它永远不会为空。不确定您是否可以将其与 null 进行比较。
    • 这只是?? 运算符的更长版本,它在功能上没有任何改变。也解决不了问题。
    • @BillGregg 我的印象是z1z2 可能是多种类型,其中一些可以为空。
    • @JeroenVannevel 有区别。三元运算符不会引发错误。 ?? 运营商可以。
    • @SamIam:很公平,功能有所不同。但是这种情况不会发生,因为 double 首先不能是 null
    【解决方案3】:

    ??用于表示“如果左侧为空,则使用右侧的值”。由于 Double 是一种值类型,因此它永远不能为空。因此,您将始终只获得属性的左侧。编译器告诉你你的代码可疑。

    使用双重?如果你想保持完全相同的代码。

    【讨论】:

    • 不,我不是说替换 ??。你的问题是类型。双倍的 ?? double 无效,因为 double 不能为空。但是双倍? ??双倍的?是有效的,因为双?是一个可以为空的双精度。这是一种不同的类型。
    • 感谢您的意见。您如何建议更改代码?
    【解决方案4】:

    我想出了一个可行的简单(长)解决方案。这是合并列表的代码

            List<Project> lst = new List<Project>();
    
            for (int i = 0; i < lst1.Count; i++)
            {
                double cusnum = 0;
                var lst2q = (from s in lst2
                                where s.ProjectId == lst1[i].ProjectId
                                select s).ToArray();
    
                if (lst2q.Length > 0)
                {
                    cusnum = lst2q[0].CustomerNum;
                }
    
    
                var lst3q = (from s in lst3
                             where s.ProjectId == lst1[i].ProjectId
                             select s).ToArray();
    
                double cusadd = 0;
                if (lst3q.Length > 0)
                {
                    cusadd = lst3q[0].Address;
                }
    
                lst.Add(new Project
                    {
                        ProjectId = lst1[i].ProjectId,
                        ProjectName = lst1[i].ProjectName,
                        CustomerNum = cusnum,
                        Address = cusadd,
                    });
            }
    

    【讨论】:

      猜你喜欢
      • 2017-12-27
      • 2017-03-17
      • 1970-01-01
      • 2021-01-06
      • 2019-01-18
      • 2021-03-22
      • 2023-03-23
      • 2019-01-22
      • 1970-01-01
      相关资源
      最近更新 更多