2012-12-22 16 views
8

Beim Spielen mit Reflektion im neuen .NET Framework 4.5 stieß ich auf ein seltsames Verhalten, das ich ziemlich unerwartet fand. Der Namespace System.Reflection bietet einige neue Erweiterungsmethoden zum Ausnutzen von Type-Objekten. Zwei davon sind GetRuntimeProperty (String-Name) und GetRuntimeProperties().Reflection: inkonsistentes Framework-Verhalten mit GetRuntimeProperty-Methoden

Stellen Sie sich nun vor, Sie hätten ein einfaches Objekt mit einer internen Eigenschaft.

public class ObjectBase 
{ 
    protected int Id { get; set; } 
    public string Name { get; set; } 
} 

Und Sie versuchen jetzt, diesen Typ auszunutzen.

var properties = typeof(ObjectBase).GetRuntimeProperties(); 
// properties.Count = 2 

var idProperty = typeof(ObjectBase).GetRuntimeProperty("Id"); 
var nameProperty = typeof(ObjectBase).GetRuntimeProperty("Name"); 
// idProperty = null 
// nameProperty = System.String Name 

Wie erwartet das properties Objekt enthält zwei Eigenschaftsdefinition für die Id und Name-Eigenschaft defintions und die nameProperty hält die Eigenschaft Name Definition. Was nicht erwartet wurde, war das idProperty Objekt null zu sein ...

Kommen aus dem .NET Framework, ich denke, das war von Microsoft Architekten gedacht, aber ich muss sagen, es scheint nicht etwas, was Sie wirklich erwarten würde passieren. Ich glaube, dass sich ähnliche Methoden ähnlich verhalten sollten, aber GetRuntimeProperty scheint nach öffentlichen Eigenschaften zu filtern, bei denen GetRuntimeProperties keine Filter anwendet.

Hat jemand eine vernünftige Erklärung dafür, warum Microsoft entschieden hat, dass diese ähnlichen Methoden unterschiedliche Verhaltensweisen haben sollten? Ein Designfehler?

Danke.

+0

Beachten Sie, dass die Verwendung nur in einer Store-App erforderlich ist. Also, was Sie sehen, ist ein Kompromiss, IInspectable ist nicht gerade eine reiche Schnittstelle. –

+0

Sie haben die neuen Reflektions-APIs komplett bugsiert. Es ist ein Durcheinander auf so viele Arten, dass ich nicht einmal weiß, wo ich anfangen soll. –

Antwort

3

Intern GetRuntimeProperty Anrufe Type.GetProperty(name), die nach der öffentlichen Eigenschaft mit dem angegebenen Namen sucht. Property Id ist geschützt, daher kann es nicht gefunden werden.

public static PropertyInfo GetRuntimeProperty(this Type type, string name) 
{ 
    CheckAndThrow(type); 
    return type.GetProperty(name); 
} 

Auf der anderen Seite GetRuntimeProperties kehrt sowohl öffentliche als auch nicht-öffentliche Eigenschaften

public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type) 
{ 
    CheckAndThrow(type); 
    return type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | 
           BindingFlags.Static | BindingFlags.Instance); 
} 

Explanation:GetRuntimeProperties Zweck kehrt IEnumerable<PropertyInfo> Sammlung aller Eigenschaften, Sie verlassen mit Filtern dass die Sammlung über LINQ. Sie können öffentliche, nicht öffentliche oder andere Arten von Eigenschaften auswählen. Mit einer einzigen Eigenschaft, die von GetRuntimeProperty zurückgegeben wird, benötigen Sie diese Flexibilität nicht, daher ist sie für die gebräuchlichste Verwendung eingeschränkt.

+4

Die Frage ist: schüchtern ist das so gestaltet. Macht nicht viel Sinn. Scheint wie ein Designfehler für mich. – Steven

+0

Wie @Steven sagte, verstehe ich eigentlich, dass es intern so codiert ist, aber was ich nicht verstehe, ist, warum diese Methoden sich anders verhalten. Ich habe meine Frage aktualisiert, um klarer zu sein. Vielen Dank. – Ucodia

+1

@Ucodia, Steven - Ich habe Erklärung und Link hinzugefügt. Wie Sie sehen können, ist das eine Designentscheidung. Wenn Sie nicht-öffentliche Eigenschaft benötigen, verwenden Sie LINQ, um es zu erhalten 'typeof (ObjectBase) .GetRuntimeProperties(). Single (p => p.Name ==" Id ")' –

Verwandte Themen