Artech's blog से देखकर और फिर हमने टिप्पणियों में चर्चा की। चूंकि वह ब्लॉग केवल चीनी में लिखा गया है, इसलिए मैं यहां एक संक्षिप्त स्पष्टीकरण ले रहा हूं। कोड पुन: पेश करने:GetHashCode और Equals को System.Attribute में गलत तरीके से लागू किया गया है?
[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
हो जाता है और एक जिसका नाम 'सी' है निकालता है। स्पष्ट रूप से आउटपुट "ए" और "बी" है? अगर सबकुछ आसानी से चल रहा था तो आपको यह सवाल नहीं दिखाई देगा। असल में आपको "एसी" "बीसी" या यहां तक कि सही "एबी" भी मिलेगा (मुझे अपनी मशीन पर एसी मिली, और ब्लॉग लेखक को बीसी मिला)। सिस्टम में 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.GetFields
तो गुण आधार वर्ग से विरासत में मिली अनदेखी कर रहे हैं, इसलिए FooAttribute
के तीन उदाहरणों की समतुल्यता (और फिर Remove
विधि एक यादृच्छिक रूप से लेता है)। तो सवाल यह है कि क्या कार्यान्वयन के लिए कोई विशेष कारण है? या यह सिर्फ एक बग है?
मैं कहूंगा कि यह एक बग है, हालांकि मुझे वास्तविक दुनिया परिदृश्य इमेजिंग में कठिनाई है, जहां इससे कोई समस्या होगी। आप इसे connect.microsoft.com पर रिपोर्ट करने पर विचार कर सकते हैं। – Joe
बग बराबर() में है, यह समान मान वापस करने के लिए GetHashCode() के लिए ठीक है। सहमत हैं, कनेक्ट पर इसे पोस्ट करें। मुझे वास्तव में संदेह है कि वे इसे ठीक करेंगे क्योंकि यह एक तोड़ने वाला बदलाव होगा। –
@ हंसपैसेंट: आप सही हैं। यहां मैं 'गेटहाशकोड' का कोड पोस्ट करता हूं क्योंकि लेखक कोड पोस्ट करता है और मेरे पास इस पीसी में कोई असहज नहीं है। –