I can't help but feel like this is a bug:
void Main() { typeof(Test).GetProperty("TestString").GetCustomAttributes().Dump(); //dumps 1 item typeof(Test).GetProperty("TestString").GetCustomAttributes(inherit:true).Dump(); // dumps 0 items typeof(Test).GetProperty("TestString").GetCustomAttributes(inherit:false).Dump(); // dumps 0 items } // Define other methods and classes here class TestBase { [TestAttribute] public virtual string TestString {get;set; } } class Test : TestBase { public override string TestString {get;set; } } [AttributeUsage(AttributeTargets.Property, Inherited = true)] class TestAttribute : Attribute {}
Are property attributes even supposed to be inheritable? ReSharper doesn't seem to think so, giving you a warning that "Inherited = true" only applies to AttributeTargets.Class and AttributeTargets.Method, and either does GetCustomAttributes(bool inherit). Why would the parameterless version return the attribute?
Next up: why are all the GetRuntimeXXX() methods extensions on Type and not extensions on TypeInfo? I thought the whole point of the reflection API redesign was to make Type just a reference to a type, and TypeInfo to require a load and contain all the actual type shape and information. Doesn't this design fly in the face of this distinction? I don't understand why they aren't just plain methods on TypeInfo instead of extensions on Type.
Why does TypeInfo inherit from Type in .NET but not in .NET Core and UWP? This causes confusion because all the extensions mentioned above are now available on both Type and TypeInfo on .NET, and introduces more API differences between the platforms. Now you need to go to TypeInfo to get some stuff, while other stuff you can just grab from Type but it will still cause an assembly load, and stuff is just all over the place. This is further confused by the fact that the API docs for .NET Core show that the class declaration for TypeInfo DOES in fact inherit from Type. Whaaaa??
Why does GetRuntimeProperties() return non-public members but GetRuntimeProperty(name) doesn't? This completely violates the principle of least surprise. This would almost be forgivable if the difference was documented in the method docs but it isn't.
Is there actually a point to the GetRuntimeXXX? It seems to me that GetProperties and GetProperty are available everywhere. When should you pick one over the other now?
There are more things that I can't remember off the top of my head but this is honestly the most botched API refresh I've seen come out of Microsoft. The only other thing that comes close is the mess of inconsistencies between generic and non-generic collection interfaces/classes. Writing a portable library that heavily depends on reflection has been quite the exercise in patience these last couple months.
I really wish there was an opportunity to do a "clean break" where all the past mistakes of the framework could be cleaned up, especially the collection classes/interfaces situation because those are used all the time. But I'm guessing that's never going to happen...I was hoping .NET Core was going to be that clean break and clean everything up in a sensible way but it didn't :(