Linq .Except 函数“至少一个对象必须实现 IComparable。”

发布于 2024-10-12 04:20:08 字数 2182 浏览 6 评论 0原文

基本上我有一个实现 IEquatable 的容器(示例如下所示)

public class ContainerClass  : IEquatable<ContainerClass>
{
        public IEnumerable<CustomClass> CustomClass { get; set; }

        public override bool Equals(object obj) { ... }
        public bool Equals(ContainerClass other) { ... }
        public static bool operator ==(ContainerClass cc1, ContainerClass cc2) { ... }
        public static bool operator !=(ContainerClass cc1, ContainerClass cc2) { ... }
        public override int GetHashCode() { ... }
}

和一个也实现 IEquatable 的 CustomClass

public class CustomClass : IEquatable<CustomClass>
{
        public string stringone { get; set; }
        public string stringtwo { get; set; }

        public override bool Equals(object obj) { ... }
        public bool Equals(CustomClass other) { ... }
        public static bool operator ==(CustomClass cc1, CustomClass cc2) { ... }
        public static bool operator !=(CustomClass cc1, CustomClass cc2) { ... }
        public override int GetHashCode() { ... }
}

所有这些工作正常,因此例如,以下工作

IEnumerable<CustomClass> customclassone = new List<CustomClass>
    {
        new CustomClass { stringone = "hi" },
        new CustomClass { stringone = "lo" }
    };
IEnumerable<CustomClass> customclasstwo = new List<CustomClass>
    {
        new CustomClass { stringone = "hi" }
    };

var diff = customclassone.Except(customclasstwo);

ContainerClass containerclassone = new ContainerClass 
{
    CustomClass = customclassone.AsEnumerable()
};
ContainerClass containerclasstwo = new ContainerClass 
{
    CustomClass = customclasstwo.AsEnumerable()
};

var diff2 = containerclassone.CustomClass.Except(customclasstwo.CustomClass);

在此代码之后,枚举时 diff 和 diff2 都包含预期结果。但是,如果我然后尝试

IEnumerable<CustomClass> oldCustom = oldContainerClass.CustomClass;
IEnumerable<CustomClass> newcustom = newContainerClass.CustomClass;
var exceptlist = oldCustom.Except(newcustom);

当我尝试枚举例外列表时,我会得到“至少一个对象必须实现 IComparable”。 oldCustom 和 newCustom 与上述工作示例中的唯一区别在于它们的填充方式。有人知道为什么会发生这种情况吗?

Basically i have a container which implements IEquatable (sample shown below)

public class ContainerClass  : IEquatable<ContainerClass>
{
        public IEnumerable<CustomClass> CustomClass { get; set; }

        public override bool Equals(object obj) { ... }
        public bool Equals(ContainerClass other) { ... }
        public static bool operator ==(ContainerClass cc1, ContainerClass cc2) { ... }
        public static bool operator !=(ContainerClass cc1, ContainerClass cc2) { ... }
        public override int GetHashCode() { ... }
}

and a CustomClass which also implements IEquatable

public class CustomClass : IEquatable<CustomClass>
{
        public string stringone { get; set; }
        public string stringtwo { get; set; }

        public override bool Equals(object obj) { ... }
        public bool Equals(CustomClass other) { ... }
        public static bool operator ==(CustomClass cc1, CustomClass cc2) { ... }
        public static bool operator !=(CustomClass cc1, CustomClass cc2) { ... }
        public override int GetHashCode() { ... }
}

All this is working fine, so for example, the following works

IEnumerable<CustomClass> customclassone = new List<CustomClass>
    {
        new CustomClass { stringone = "hi" },
        new CustomClass { stringone = "lo" }
    };
IEnumerable<CustomClass> customclasstwo = new List<CustomClass>
    {
        new CustomClass { stringone = "hi" }
    };

var diff = customclassone.Except(customclasstwo);

ContainerClass containerclassone = new ContainerClass 
{
    CustomClass = customclassone.AsEnumerable()
};
ContainerClass containerclasstwo = new ContainerClass 
{
    CustomClass = customclasstwo.AsEnumerable()
};

var diff2 = containerclassone.CustomClass.Except(customclasstwo.CustomClass);

After this code both diff and diff2 when enumerated contain the expected results. However, if i then try

IEnumerable<CustomClass> oldCustom = oldContainerClass.CustomClass;
IEnumerable<CustomClass> newcustom = newContainerClass.CustomClass;
var exceptlist = oldCustom.Except(newcustom);

When i try to enumerate the exceptlist i get "At least one object must implement IComparable.". The only difference between oldCustom and newCustom from the ones in the above working examples is the way they are populated. Anyone got any idea why this is happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

唯憾梦倾城 2024-10-19 04:20:08

我怀疑您试图对 ContainerClass.CustomClass 的这些内容进行排序。由于延迟执行,除非您迭代它,否则您不会知道存在问题,而 Except() 只是一个转移注意力的东西。 CustomClass 未实现 IComparable 接口,因此排序失败并出现该错误。您的 CustomClass 应该实现 IComparable 接口,或者您应该在 OrderBy() 上传入 IComparer >。

例如,

oldContainerClass.CustomClass = someListOfSomeType.OrderBy(x => x.CustomClasss, myComparer)
                                                  .Select(x => x.CustomClass);

尽管了解您分配给这些属性的具体内容会有所帮助,以便我们可以为您提供更准确的原因。

I suspect that you attempted to sort these contents of the ContainerClass.CustomClass. Due to the deferred execution, you don't know there's a problem until you iterate through it and Except() is just a red herring. CustomClass doesn't implement the IComparable interface so the sort fails with that error. Your CustomClass should either implement the IComparable<T> interface or you should pass in an IComparer on your OrderBy().

e.g.,

oldContainerClass.CustomClass = someListOfSomeType.OrderBy(x => x.CustomClasss, myComparer)
                                                  .Select(x => x.CustomClass);

Though it would help to see what exactly you assigned to these properties so we can give you a more precise reason.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文