相关疑难解决方法(0)

Distinct()与lambda?

是的,所以我有一个可枚举的,并希望从中获得不同的值.

使用System.Linq,当然有一个名为的扩展方法Distinct.在简单的情况下,它可以在没有参数的情况下使用,例如:

var distinctValues = myStringList.Distinct();
Run Code Online (Sandbox Code Playgroud)

好的,但如果我有一个可以指定相等性的可枚举对象,唯一可用的重载是:

var distinctValues = myCustomerList.Distinct(someEqualityComparer);
Run Code Online (Sandbox Code Playgroud)

equality comparer参数必须是.的实例IEqualityComparer<T>.当然,我可以做到这一点,但它有点冗长,而且很有说服力.

我所期望的是一个需要lambda的重载,比如Func <T,T,bool>:

var distinctValues
    = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);
Run Code Online (Sandbox Code Playgroud)

任何人都知道是否存在某些此类扩展或某些等效的解决方法?或者我错过了什么?

或者,有没有一种方法可以指定IEqualityComparer内联(embarass me)?

更新

我找到了Anders Hejlsberg对MSDN论坛中关于这个主题的帖子的回复.他说:

您将遇到的问题是,当两个对象比较相等时,它们必须具有相同的GetHashCode返回值(否则Distinct内部使用的哈希表将无法正常运行).我们使用IEqualityComparer,因为它将Equals和GetHashCode的兼容实现打包到一个接口中.

我认为那是有道理的..

c# lambda extension-methods c#-3.0

714
推荐指数
8
解决办法
37万
查看次数

GetHashCode在.NET中的IEqualityComparer <T>中的作用是什么?

我试图理解IEqualityComparer接口的GetHashCode方法的作用.

以下示例来自MSDN:

using System;
using System.Collections.Generic;
class Example {
    static void Main() {
        try {

            BoxEqualityComparer boxEqC = new BoxEqualityComparer();

            Dictionary<Box, String> boxes = new Dictionary<Box,
                                                string>(boxEqC);

            Box redBox = new Box(4, 3, 4);
            Box blueBox = new Box(4, 3, 4);

            boxes.Add(redBox, "red");
            boxes.Add(blueBox, "blue");

            Console.WriteLine(redBox.GetHashCode());
            Console.WriteLine(blueBox.GetHashCode());
        }
        catch (ArgumentException argEx) {

            Console.WriteLine(argEx.Message);
        }
    }
}

public class Box {
    public Box(int h, int l, int w) {
        this.Height = h;
        this.Length = l;
        this.Width = w;
    }
    public int …
Run Code Online (Sandbox Code Playgroud)

.net c# iequalitycomparer gethashcode

137
推荐指数
3
解决办法
3万
查看次数

c#比较两个通用值

可能重复:
不能将运算符==应用于C#中的泛型类型?

我编写了这样的代码:

public bool IsDataChanged()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return (valueInDB != valueFromView);
}
Run Code Online (Sandbox Code Playgroud)

现在该函数没有编译错误" 运算符'!='不能应用于'T'和'T'类型的操作数 ".我该怎么做才能使这个功能起作用?

c# generics

68
推荐指数
3
解决办法
7万
查看次数

如何在多个字段中使用LINQ Distinct()

我有从数据库派生的以下EF类(简化)

class Product
{ 
     public string ProductId;
     public string ProductName;
     public string CategoryId;
     public string CategoryName;
}
Run Code Online (Sandbox Code Playgroud)

ProductId是表的主键.

对于DB设计者做出的糟糕的设计决策(我无法修改它),我有CategoryIdCategoryName在这个表中.

我需要一个DropDownList的使用(不同)CategoryId价值,并CategoryName文本.因此我应用了以下代码:

product.Select(m => new {m.CategoryId, m.CategoryName}).Distinct();
Run Code Online (Sandbox Code Playgroud)

从逻辑上讲,它应该使用CategoryIdCategoryName作为属性创建一个匿名对象.在Distinct()保证有没有重复对(CategoryId,CategoryName).

但实际上它不起作用.据我所知,Distinct()当集合中只有一个字段时,它就会忽略它们......这是正确的吗?有没有解决方法?谢谢!

UPDATE

对不起product是:

List<Product> product = new List<Product>();
Run Code Online (Sandbox Code Playgroud)

我找到了另一种获得相同结果的方法Distinct():

product.GroupBy(d => new {d.CategoryId, d.CategoryName}) 
       .Select(m => new {m.Key.CategoryId, m.Key.CategoryName})
Run Code Online (Sandbox Code Playgroud)

c# linq distinct

62
推荐指数
5
解决办法
16万
查看次数

IEqualityComparer <T>使用ReferenceEquals

是否有使用的默认IEqualityComparer<T>实现ReferenceEquals

EqualityComparer<T>.Default使用ObjectComparer,它使用object.Equals().在我的例子中,对象已经实现IEquatable<T>,我需要忽略并仅通过对象的引用进行比较.

.net c# iequalitycomparer referenceequals

57
推荐指数
4
解决办法
7115
查看次数

传递lambda表达式代替IComparer或IEqualityComparer或任何单方法接口?

我碰巧看到了一些代码,其中这个人将lambda表达式传递给ArrayList.Sort(这里是IComparer)或IEnumerable.SequenceEqual(IEnumerable列表,IEqualityComparer here),其中需要IComparer或IEqualityComparer.

我不能确定我是否看过它,或者我只是在做梦.我似乎无法在这些集合中找到任何接受Func <>或其方法签名中的委托的扩展.

有这样的过载/扩展方法吗?或者,如果没有,是否有可能像这样捣乱并传递一个算法(读委托),其中预期单方法接口?

更新 谢谢大家.那正是我所想.我一定是在做梦.我知道如何编写转换.我只是不确定我是否见过这样的东西,或者只是觉得我已经看过了.

又一次更新 看,在这里,我找到了一个这样的实例.毕竟我并没有做梦.看看这家伙这做什么.是什么赋予了?

这是另一个更新: 好的,我明白了.那家伙正在使用Comparison<T>超载.尼斯.很好,但完全容易误导你.不过很好.谢谢.

linq ienumerable extension-methods icomparer iequalitycomparer

56
推荐指数
6
解决办法
4万
查看次数

匿名IComparer实现

是否可以定义IComparer的匿名实现?

我相信Java允许内联定义匿名类 - C#?

看看这段代码我想定义一个自定义IComparer内联

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer
)
Run Code Online (Sandbox Code Playgroud)

c#

43
推荐指数
4
解决办法
2万
查看次数

IEqualityComparer为匿名类型

我有这个

 var n = ItemList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList();
 n.AddRange(OtherList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList(););
Run Code Online (Sandbox Code Playgroud)

如果允许,我想这样做

n = n.Distinct((x, y) => x.Vchr == y.Vchr)).ToList();
Run Code Online (Sandbox Code Playgroud)

我尝试使用通用的LambdaComparer,但由于我使用的是匿名类型,因此没有类型与之关联.

"帮助我Obi Wan Kenobi,你是我唯一的希望"

linq lambda anonymous-types iequalitycomparer

33
推荐指数
1
解决办法
1万
查看次数

在.NET中有任何类型的"ReferenceComparer"吗?

BCL中有几个地方可以使用IEqualityComparer.像Enumerable.ContainsDictionary Constructor.如果我对默认的不满意,我可以提供我的比较器.

有时我想知道集合是否包含我所引用的那个对象.不是任何其他意义上被认为"相等"的那个.
问题是:BCL中是否存在仅依赖于ReferenceEquals方法的标准相等比较器?

我自己写的是这样的:

class ReferenceComparer<T> : IEqualityComparer<T> where T : class
{
    private static ReferenceComparer<T> m_instance;

    public static ReferenceComparer<T> Instance
    {
        get
        {
            return m_instance ?? (m_instance = new ReferenceComparer<T>());
        }
    }

    public bool Equals(T x, T y)
    {
        return ReferenceEquals(x, y);
    }

    public int GetHashCode(T obj)
    {
        return RuntimeHelpers.GetHashCode(obj);
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有测试它彻底,也没有考虑很多的场景,但它似乎使Enumerable.ContainsDictionary很高兴.

.net c# comparison base-class-library

18
推荐指数
1
解决办法
1867
查看次数

将[AutoFixture] SemanticComparison OfLikeness应用于序列/集合/数组/ IEnumerable

我们编写了一个如下所示的测试.此测试要求我们EqualCodeTableItem-class 创建了en -overload :

ICollection<CodeTableItem> expectedValutaList = new List<CodeTableItem>();
expectedValutaList.Add(new CodeTableItem("DKK", "DKK"));
expectedValutaList.Add(new CodeTableItem("EUR", "EUR"));
RepoDac target = new RepoDac(); 

var actual = target.GetValutaKd();

CollectionAssert.AreEqual(expectedValutaList.ToList(),actual.ToList());
Run Code Online (Sandbox Code Playgroud)

测试工作正常,但是对Equality函数有一个不幸的依赖,这意味着如果我CodeTableItem用一个字段扩展-class,并忘记扩展Equals-function,单元测试仍然会运行绿色,尽管我们不测试所有字段.我们希望避免这种Equality污染(参见测试特定平等),这种污染只是为了符合测试而编写的.

我们尝试过使用OfLikeness,并以这种方式重写了测试:

ICollection<CodeTableItem> expectedValutaList = new List<CodeTableItem>();
expectedValutaList.Add(new CodeTableItem("DKK", "DKK"));
expectedValutaList.Add(new CodeTableItem("EUR", "EUR"));
var expectedValutaListWithLikeness = 
          expectedValutaList.AsSource().OfLikeness<List<CodeTableItem>>();

RepoDac target = new RepoDac(); 
ICollection<CodeTableItem> actual;

actual = target.GetValutaKd();

expectedValutaListWithLikeness.ShouldEqual(actual.ToList());
Run Code Online (Sandbox Code Playgroud)

但测试失败是因为Capacity不相等.我编写了多次运行反射的代码,并且通常最终实现了忽略字段的重载.有没有办法用OfLikeness或忽略某些字段ShouldEqual?或者还有其他方法可以解决这个问题吗?

.net collections unit-testing autofixture semantic-comparison

12
推荐指数
2
解决办法
2836
查看次数