I am employing a logic similar to the suggestion present in the Microsoft documentation https://msdn.microsoft.com/en-us/library/cs58sb90(v=vs.110).aspx to retrieve the custom attributes given to the parameter of a method.
However, I find this approach expensive as it uses reflection to retrieve the custom attributes, I am wondering if there is any better approach to this problem than using reflection?
The short answer as far as I am aware is no, reflection is the standard and probably only way to retrieve attributes.
However, attributes are fixed in the type metadata at compile-time, which means you will only ever have to inspect them once for each type during the lifetime of your program, and they won't change in that time unless your code is doing some really wacky runtime type construction (e.g. with Reflection.Emit). Even if you don't know the exact type of any object your code requires the attributes of, you could still cache the type's attributes in a dictionary to save looking them up again, if you're really that concerned about performance.
Related
I'd like to use C#'s reflection and custom attributes to simplify registering a series of types with a central management class (i.e. it provides static methods taking a string key and invoking/retrieving the proper method/parameter for the associated type). Looking at other questions here and a couple places elsewhere, it seems like the best way of doing so is to simply iterate through all public types of the assembly -- since it's intended to be a library -- and check if each type has the proper attribute before adding the relevant values to the underlying Dictionaries. The reflection and iteration will definitely be slow, but I can live with it since it should only occur once.
Unfortunately, I can't figure out how to get an attribute from a type. For methods and assemblies, I can use CustomAttributeExtensions.GetCustomAttribute<MyAttribute>(base) from System.Reflection.Extensions, but that doesn't provide an overload for Type; the same for Assembly.GetCustomAttribute(Assembly, Type) and the .IsDefined(...) methods used in this question. Other suggestions use methods on the Type itself that, from the documentation, seem to be loaded from mscorelib.dll, but it didn't seem to be showing up in Intellisense even after adding the reference and I'm not sure how that .dll interacts with .NET Standard, anyway (as in, does it reduce the ability to run on arbitrary platforms at all?)
Am I missing something obvious, or is it really this hard to get an Attribute back off of a Type?
Try typeof(YourType).GetTypeInfo().GetCustomAttributes();
I have a set of strings like this:
System.Int32
string
bool[]
List<MyType.MyNestedType>
Dictionary<MyType.MyEnum, List<object>>
I would like to test if those strings are actually source code representations of valid types.
I'm in an environment, that doesn't support Roslyn and incorporating any sort of parser would be difficult. This is why I've tried using System.Type.GetType(string) to figure this out.
However, I'm going down a dirty road, because there are so many edge cases, where I need to modify the input string to represent an AssemblyQualifiedString. E.g. nested type "MyType.MyNestedType" needs to be "MyType+MyNestedType" and generics also have to be figured out the hard way.
Is there any helper method which does this kind of checking in .Net 2.0? I'm working in the Unity game engine, and we don't have any means to switch our system to a more sophisticated environment with available parsers.
Clarification
My company has developed a code generation system in Unity, which is not easily changed at this point. The one thing I need to add to it, is the ability to get a list of fields defined in a class (via reflection) and then separate them based on whether they are part of the default runtime assembly or if they are enclosed within #if UNITY_EDITOR preprocessor directives. When those are set, I basically want to handle those fields differently, but reflection alone can't tell me. Therefore I have decided to open my script files, look through the text for such define regions and then check if a field is declared within in them, and if true, put it in a separate FieldInfo[] array.
The one thing fixed and not changeable: All script will be inspected via reflection and a collection of FieldInfo is used to generate new source code elsewhere. I just need to separate that collection into individual ones for runtime vs editor assembly.
Custom types and nested generics are probably the hard part.
Can't you just have a "equivalency map to fully qualified name" or a few translation rules for all custom types ?
I guess you know by advance what you will encounter.
Or maybe run it on opposite way : at startup, scan your assembly(s) and for each class contained inside, generates the equivalent name "as it's supposed to appear" in your input file from the fully qualified name in GetType() format ?
For custom types of other assemblies, please note that you have to do things such as calling Assembly.LoadFile() or pass assembly name in second parameter to GetType() before to be able to load them.
See here for example : Resolve Type from Class Name in a Different Assembly
Maybe this answer could also help : How to parse C# generic type names?
Could you please detail what is the final purpose of project ? The problem is a bit surprising, especially for a unity project. Is it because you used some kind of weird serialization to persist state of some of your objects ?
This answer is more a few recommandations and questions to help you to clarify the needs than a definitive answer, but it can't hold in a single comment, and I think it provide useful informations
This seems like a simple question on its surface but I thought I'd reach out to the community for this one. I am serializing .NET types in a stream and need some way to uniquely identify each type so that I know how to deserialize the type on the other side. I've thought of various approaches:
Annotate each type with an attribute that requires an integer to identify the message type
Do the same as #1 except use a GUID
Hashing the fully qualified name
I would love to be able to do this without requiring the attribute. Using an integer is conflict prone. Generating GUIDs every time I create a new type is cumbersome. The third option seems possible but also has the possibility of conflicts, albeit somewhat isolated.
What I'd like to be able to do is infer this uniqueness in a deterministic way so that any object can be passed in and deserialized on the other end without having to mark it up somehow. Assume that I already have a way to register all known types on both ends, so before any message is sent, both ends already have a list of acceptable types. All I'd like to do is make the process of registering those known types less clunky.
Edit: I'd like to be as small on the wire as possible while still achieving the uniqueness I require.
You could use Type.GUID for example...
IF that does not fit your case please provide more details...
In addition to answers available I would suggest to use fully quaified type name. It already guarantees uniquness inside your application domain.
I am currently populating my WPF grid using a data collection that implements ITypedList, with the contained entities implementing ICustomTypeDescriptor. All the properties are determined at runtime.
I'm wanting to implement HyperDescriptor to help speed up performance, but the example on that page more refers to known types rather than runtime properties.
I would think that I'd need to implement a custom GetProperties() method or similar to tell the HyperTypeDescriptor what properties it needs to look at, but am not sure where that should be set. I figure it's not difficult, but I'm obviously missing something.
Any tips much appreciated!
The HyperDescriptor implementation is indeed specific for compile-time properties, as it uses ILGenerator etc and caches the generated code. If you are using ICustomDescriptor you are already in a very different performance profile - for example, if your custom PropertyDescriptors work against a dictionary or hash-table as a property-bag they may already be significantly faster than raw reflection.
It may be possible to further optimise it, but I'd need to know more about the specific implementation. But it would be non-trivial work, so first satisfy yourself that this member-access is actually a bottleneck, and that you couldn't do something simple like paging or "virtual mode" first.
(clarification: I'm the author of HyperDescriptor, so I know this area well)
Are there specific cases when one should use custom attributes on class instead of properties?
I know that properties are preferrable because of their discoverability and performance, but attributes... When should I definitely use them?
UPDATE:
Here is a post by Eric Lippert about this decision.
Eric Lippert has a great blog post tackling exactly this decision.
His summary is:
In short: use attributes to describe your mechanisms, use properties to model the domain.
I'd also add to that the consideration that an attribute value is effectively static - in other words it's part of the description of the type rather than any instance of the type.
One tricky bit can come when every instance of some base type has to have a property (e.g. a description) but different concrete derived types want to specify descriptions on a per-type basis rather than per-instance. You often end up with virtual properties which always return constants - this isn't terribly satisfactory. I suspect Delphi's class references might help here... not sure.
EDIT: To give an example of a mechanism, if you decorate a type to say which table it's from in the database, that's describing the data transfer mechanism rather than saying anything about the model of data that's being transferred.
There are two use cases:
1) Using a custom attribute that someone else has defined, such as the System.LoaderOptimization attribute that may be used on the Main method. These kinds of attributes are used to direct platform code such as the CLR, WPF, WCF or the debugger to run the code in a certain way, and can be very useful at times. Reading books on various platform topic is a good way to learn when and how to use these attributes.
2) Creating your own custom attribute and using it to decorate a class (or method, property, etc). These have no effect unless you also have code that uses Reflection to notice those attribute usages and change the behavior in some way. This usages should be avoided whenever possible because of very poor performance, orders of magnitude larger than, say, accessing a static member of a class.