English 中文(简体)
在系统中,“GetHashCode”和“平等”的实施是不正确的。 营养吗?
原标题:GetHashCode and Equals are implemented incorrectly in System.Attribute?

Seeing from ,然后我们在评论中进行了讨论。 由于该博客仅用中文书写,我在此作简要解释。 生殖法:

[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public abstract class BaseAttribute : Attribute
{
    public string Name { get; set; }
}

public class FooAttribute : BaseAttribute { }

[Foo(Name = "A")]
[Foo(Name = "B")]
[Foo(Name = "C")]
public class Bar { }

//Main method
var attributes = typeof(Bar).GetCustomAttributes(true).OfType<FooAttribute>().ToList<FooAttribute>();
var getC = attributes.First(item => item.Name == "C");
attributes.Remove(getC);
attributes.ForEach(a => Console.WriteLine(a.Name));

该守则载有所有<代码>FooAttribute,删除了名称为“C”的代码。 产出显然是“A”和“B”? 如果一切顺利进行,你就没有看到这个问题。 事实上,你会从理论上获得“AC”“BC”或甚至正确的“AB”(I got AC在我的机器上,博客作者会到B)。 问题产生于在系统中实施GetHashCode/Equals。 人均 执行摘要:

  [SecuritySafeCritical]
  public override int GetHashCode()
  {
      Type type = base.GetType();
      //*****NOTICE*****
      FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic 
            | BindingFlags.Public 
            | BindingFlags.Instance);
      object obj2 = null;
      for (int i = 0; i < fields.Length; i++)
      {
          object obj3 = ((RtFieldInfo) fields[i]).InternalGetValue(this, false, false);
          if ((obj3 != null) && !obj3.GetType().IsArray)
          {
              obj2 = obj3;
          }
          if (obj2 != null)
          {
              break;
          }
      }
      if (obj2 != null)
      {
          return obj2.GetHashCode();
      }
      return type.GetHashCode();
  }

它使用<代码>Type.Get Fields,因此忽视了从基类继承的财产,因此,“FooAttribute(然后是<代码>Remove方法有一个<>randomly)。 因此,问题是:是否有执行的特别理由? 或者这只是一个ug子吗?

最佳回答

A clear bug, no. 2. 一个好的想法,或许不是。

它意味着一件事等于另一件? 如果我们真的想要,我们就能够取得相当的哲学。

仅仅只是略微的哲学,一些东西必须持有:

  1. Equality is reflexive: Identity entails equality. x.Equals(x) must hold.
  2. Equality is symmetric. If x.Equals(y) then y.Equals(x) and if !x.Equals(y) then !y.Equals(x).
  3. Equality is transitive. If x.Equals(y) and y.Equals(z) then x.Equals(z).

还有其他几个方面,但只有这些内容才能直接反映在<条码>上。

If an implementation of an override of object.Equals(object), IEquatable<T>.Equals(T), IEqualityComparer.Equals(object, object), IEqualityComparer<T>.Equals(T, T), == or of != does not meet the above, it s a clear bug.

The other method that reflects equality in .NET are object.GetHashCode(), IEqualityComparer.GetHashCode(object) and IEqualityComparer<T>.GetHashCode(T). Here there s the simple rule:

If a.Equals(b) then it must hold that a.GetHashCode() == b.GetHashCode(). The equivalent holds for IEqualityComparer and IEqualityComparer<T>.

如果这种搁置,那么我们就会再次 b。

此外,对于平等必须意味着什么,没有过于广泛的规则。 它取决于其本身的<条码>(......)高于一切的类别或平等比较者强加于它的类别。 当然,这些批评意见要么是显而易见的,要么是在阶级或平等比较中记载的。

总而言之,<代码>Equals和/或GetHashCode a bug:

  1. If it fails to provide the reflexive, symmetric and transitive properties detailed above.
  2. If the relationship between GetHashCode and Equals is not as above.
  3. If it doesn t match its documented semantics.
  4. If it throws an inappropriate exception.
  5. If it wanders off into an infinite loop.
  6. In practice, if it takes so long to return as to cripple things, though one could argue there s a theory vs. practice thing here.

在<代码>Attribute上,等同物确实具有弹性、不对称和过境特性,其编号为与代码相符,其文件编号为:

本年度行动计划对此表示支持。 NET 框架基础设施,并不打算直接从你的法典中加以利用。

你们真的可以说,你们的榜样使!

由于你抱怨说,其中任何一个点都失败了,这并不是一ug。

这部法典有了一个 though:

var attributes = typeof(Bar).GetCustomAttributes(true).OfType<FooAttribute>().ToList<FooAttribute>();
var getC = attributes.First(item => item.Name == "C");
attributes.Remove(getC);

你首先要求一个符合标准的项目,然后要求删除一个与标准相同的项目。 没有理由不审查有关类型平等问题的属性,以期望删除<条码>的植被/代码>。

你们应该做的是:

bool calledAlready;
attributes.RemoveAll(item => {
  if(!calledAlready && item.Name == "C")
  {
    return calledAlready = true;
  }
});

That is to say, we use a predicate that matches the first attribute with Name == "C" and no other.

问题回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签