Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# } 公共int GetHashCode(T obj) { if(obj==null) 返回0; var散列=\u属性 .Select(pi=>pi.GetValue(obj)?.GetHashCode()???0.ToArray(); 返回联合收割机(散列_C#_Linq_Distinct - Fatal编程技术网

C# } 公共int GetHashCode(T obj) { if(obj==null) 返回0; var散列=\u属性 .Select(pi=>pi.GetValue(obj)?.GetHashCode()???0.ToArray(); 返回联合收割机(散列

C# } 公共int GetHashCode(T obj) { if(obj==null) 返回0; var散列=\u属性 .Select(pi=>pi.GetValue(obj)?.GetHashCode()???0.ToArray(); 返回联合收割机(散列,c#,linq,distinct,C#,Linq,Distinct,} 公共int GetHashCode(T obj) { if(obj==null) 返回0; var散列=\u属性 .Select(pi=>pi.GetValue(obj)?.GetHashCode()???0.ToArray(); 返回联合收割机(散列); } 静态int组合(int[]散列) { int结果=0; foreach(散列中的var散列) { uint rol5=((uint)结果>27); 结果=((int)rol5+result)^hash; } 返回结果; } 静态属性I

} 公共int GetHashCode(T obj) { if(obj==null) 返回0; var散列=\u属性 .Select(pi=>pi.GetValue(obj)?.GetHashCode()???0.ToArray(); 返回联合收割机(散列); } 静态int组合(int[]散列) { int结果=0; foreach(散列中的var散列) { uint rol5=((uint)结果>27); 结果=((int)rol5+result)^hash; } 返回结果; } 静态属性Info ExtractProperty(表达式属性) { if(property.NodeType!=ExpressionType.Lambda) throwEx(); var body=property.body; if(body.NodeType==ExpressionType.Convert) if(body是一元表达式) body=一元操作数; 其他的 throwEx(); 如果(!(正文是MemberExpression成员)) throwEx(); 如果(!(member.member是PropertyInfo pi)) throwEx(); 返回pi; void throwEx()=> 抛出新的NotSupportedException($“表达式{property}不受支持。”); } }
是的,我只是通过ToLookup()来查看。可能效率低,速度慢,但可以完成此任务。在上面/下面发布我的声明我同意框架似乎缺少一些东西。我不知道这是不是一个合格的比较。。。这两种方法都需要。感觉应该有一种更简单的方法来使用Distinct:一种接受谓词的覆盖,而不是谓词。我的意思是对Distinct的重写,它将取T,让你选择你想要用于区分的对象。@charlie-对,这就是我实际上认为我将使用现有Distinct(..)得到的结果。我以前从未在这种情况下使用过它,当然,它并不是我所期望的那么好。然后你也可以实现我所希望的对Distinct的覆盖。是的,你可以很容易地做到这一点并得到你想要的。但是你不是还在实现IEqualityComparer吗。听起来好像你不想那样做。注意,这不一定行得通;不能保证您提供的GetHashCode实现与Equals方法一致。这可能会给出错误的结果。对于IEnumerable.Distinct等方法来说,在执行可能更昂贵的相等性检查之前,使用GetHashCode()函数对项目进行装箱是完全合理的。您的实现不符合IEqualityComparer的约定。忽略
TSource
参数的第二个静态创建方法有什么意义?公共静态ProjectionQualityComparer创建(TSource被忽略,Func投影){返回新的ProjectionQualityComparer(投影);}@血肉:当您可能无法显式指定类型时,它允许类型推断启动-例如,对于匿名类型。答案中的源代码中缺少ThrowIfNull,因此不会编译。这似乎是可行的:
publicstatict ThrowIfNull(这个T值,字符串variableName),其中T:class{if(value==null){throw new NullReferenceException(string.Format(“value is null:{0}”,variableName));}返回值;}
@Daryl:Yes,差不多就是这样-除了它应该抛出
ArgumentNullException
。将添加MiscUtil中的版本。。。
class GalleryImage {
   public int Key { get;set; }
   public string Caption { get;set; }
   public string Filename { get; set; }
   public string[] Tags {g et; set; }
}
var allImages = Galleries.SelectMany(x => x.Images);
var distinctImages = allImages.Distinct<GalleryImage>(new 
                     EqualityComparer<GalleryImage>((a, b) => a.id == b.id));
Galleries.SelectMany(x => x.Images).ToLookup(x => x.id).Select(x => x.First());
public class ThrowAwayEqualityComparer<T> : IEqualityComparer<T>
{
  Func<T, T, bool> comparer;

  public ThrowAwayEqualityComparer(Func<T, T, bool> comparer)   
  {
    this.comparer = comparer;
  }

  public bool Equals(T a, T b)
  {
    return comparer(a, b);
  }

  public int GetHashCode(T a)
  {
    return a.GetHashCode();
  }
}
var distinctImages = allImages.Distinct(
   new ThrowAwayEqualityComparer<GalleryImage>((a, b) => a.Key == b.Key));
public static class IEnumerableExtensions
{
  public static IEnumerable<TValue> Distinct<TValue>(this IEnumerable<TValue> @this, Func<TValue, TValue, bool> comparer)
  {
    return @this.Distinct(new ThrowAwayEqualityComparer<TValue>(comparer);
  }

  private class ThrowAwayEqualityComparer...
}
    public static IEnumerable<T> Distinct<T, U>(
        this IEnumerable<T> seq, Func<T, U> getKey)
    {
        return
            from item in seq
            group item by getKey(item) into gp
            select gp.First();
    }
    public class KeyEqualityComparer<T,U> : IEqualityComparer<T>
    {
        private Func<T,U> GetKey { get; set; }

        public KeyEqualityComparer(Func<T,U> getKey) {
            GetKey = getKey;
        }

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

        public int GetHashCode(T obj)
        {
            return GetKey(obj).GetHashCode();
        }
    }
EqualityComparer<GalleryImage> comparer = 
    ProjectionEqualityComparer<GalleryImage>.Create(x => x.id);
// Helper class for construction
public static class ProjectionEqualityComparer
{
    public static ProjectionEqualityComparer<TSource, TKey>
        Create<TSource, TKey>(Func<TSource, TKey> projection)
    {
        return new ProjectionEqualityComparer<TSource, TKey>(projection);
    }

    public static ProjectionEqualityComparer<TSource, TKey>
        Create<TSource, TKey> (TSource ignored,
                               Func<TSource, TKey> projection)
    {
        return new ProjectionEqualityComparer<TSource, TKey>(projection);
    }
}

public static class ProjectionEqualityComparer<TSource>
{
    public static ProjectionEqualityComparer<TSource, TKey>
        Create<TKey>(Func<TSource, TKey> projection)
    {
        return new ProjectionEqualityComparer<TSource, TKey>(projection);
    }
}

public class ProjectionEqualityComparer<TSource, TKey>
    : IEqualityComparer<TSource>
{
    readonly Func<TSource, TKey> projection;
    readonly IEqualityComparer<TKey> comparer;

    public ProjectionEqualityComparer(Func<TSource, TKey> projection)
        : this(projection, null)
    {
    }

    public ProjectionEqualityComparer(
        Func<TSource, TKey> projection,
        IEqualityComparer<TKey> comparer)
    {
        projection.ThrowIfNull("projection");
        this.comparer = comparer ?? EqualityComparer<TKey>.Default;
        this.projection = projection;
    }

    public bool Equals(TSource x, TSource y)
    {
        if (x == null && y == null)
        {
            return true;
        }
        if (x == null || y == null)
        {
            return false;
        }
        return comparer.Equals(projection(x), projection(y));
    }

    public int GetHashCode(TSource obj)
    {
        if (obj == null)
        {
            throw new ArgumentNullException("obj");
        }
        return comparer.GetHashCode(projection(obj));
    }
}
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>
        (this IEnumerable<TSource> source,
         Func<TSource, TKey> keySelector)
    {
        return source.DistinctBy(keySelector, null);
    }

    public static IEnumerable<TSource> DistinctBy<TSource, TKey>
        (this IEnumerable<TSource> source,
         Func<TSource, TKey> keySelector,
         IEqualityComparer<TKey> comparer)
    {
        source.ThrowIfNull("source");
        keySelector.ThrowIfNull("keySelector");
        return DistinctByImpl(source, keySelector, comparer);
    }

    private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>
        (IEnumerable<TSource> source,
         Func<TSource, TKey> keySelector,
         IEqualityComparer<TKey> comparer)
    {
        HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
        foreach (TSource element in source)
        {
            if (knownKeys.Add(keySelector(element)))
            {
                yield return element;
            }
        }
    }
public static void ThrowIfNull<T>(this T data, string name) where T : class
{
    if (data == null)
    {
        throw new ArgumentNullException(name);
    }
}
IEqualityComparer<Contact> comp1 = EqualityComparerImpl<Contact>.Create(c => c.Name);
var comp2 = EqualityComparerImpl<Contact>.Create(c => c.Name, c => c.Age);

class Contact { public Name { get; set; } public Age { get; set; } }
public class EqualityComparerImpl<T> : IEqualityComparer<T>
{
  public static EqualityComparerImpl<T> Create(
    params Expression<Func<T, object>>[] properties) =>
    new EqualityComparerImpl<T>(properties);

  PropertyInfo[] _properties;
  EqualityComparerImpl(Expression<Func<T, object>>[] properties)
  {
    if (properties == null)
      throw new ArgumentNullException(nameof(properties));

    if (properties.Length == 0)
      throw new ArgumentOutOfRangeException(nameof(properties));

    var length = properties.Length;
    var extractions = new PropertyInfo[length];
    for (int i = 0; i < length; i++)
    {
      var property = properties[i];
      extractions[i] = ExtractProperty(property);
    }
    _properties = extractions;
  }

  public bool Equals(T x, T y)
  {
    if (ReferenceEquals(x, y))
      //covers both are null
      return true;
    if (x == null || y == null)
      return false;
    var len = _properties.Length;
    for (int i = 0; i < _properties.Length; i++)
    {
      var property = _properties[i];
      if (!Equals(property.GetValue(x), property.GetValue(y)))
        return false;
    }
    return true;
  }

  public int GetHashCode(T obj)
  {
    if (obj == null)
      return 0;

    var hashes = _properties
        .Select(pi => pi.GetValue(obj)?.GetHashCode() ?? 0).ToArray();
    return Combine(hashes);
  }

  static int Combine(int[] hashes)
  {
    int result = 0;
    foreach (var hash in hashes)
    {
      uint rol5 = ((uint)result << 5) | ((uint)result >> 27);
      result = ((int)rol5 + result) ^ hash;
    }
    return result;
  }

  static PropertyInfo ExtractProperty(Expression<Func<T, object>> property)
  {
    if (property.NodeType != ExpressionType.Lambda)
      throwEx();

    var body = property.Body;
    if (body.NodeType == ExpressionType.Convert)
      if (body is UnaryExpression unary)
        body = unary.Operand;
      else
        throwEx();

    if (!(body is MemberExpression member))
      throwEx();

    if (!(member.Member is PropertyInfo pi))
      throwEx();

    return pi;

    void throwEx() =>
      throw new NotSupportedException($"The expression '{property}' isn't supported.");
  }
}