I've found that attributes in C# seem to be lazily instantiated.
[A(123)]
class A : Attribute
{
public A(int b)
{
GetType().GetCustomAttributes(true);
}
}
In this example, creating a new A instance causes a StackOverflowException, but if I remove the call to GetCustomAttributes(), then execution carries on normally.
Why is this? It makes more sense to me that attributes are properly initialized when the class they decorate is.
Why the runtime would need to instantiate all attributes on class before you requested them? It is like asking why runtime does not create an instance of my class in advance, just in case I want to use it later.
Attributes are meta data on class, they do not affect the class work in any way. Only the code the requests the attribute care about it, no one else is not. So the current behavior does make sense.
Since attribute functionality is only ever executed by code that is actively looking for the attribute in question, it's wasteful for the runtime to instantiate attributes until they are first used - indeed, during the lifetime of a program, attributes may never be inspected.
Attributes are "information" associated to a type, and not to an instance.
There is no reason why they should be instantiated when you create an object of the type they are attached to, instead you can see them when you're inspecting the type itself.
Related
I have a class, and I am doing some nifty things with reflection.
Now I have a need to add some meta data associated to a particular field when I am assigning a value to the field of a class using reflection (I don't know what the class will be).
I would like to do this without the clients to my implementation knowing (having to do anything special of their own).
Having a designated "meta" field or object within the class would work, but doesn't feel very elegant since it requires the child class to do something to be "compatible". I would like to dynamically attach this meta information to the existing class, but still allow it to be treated like the same class be the rest of the application. I would like to be able to recover this meta information later.
Class gets passed in
Values get assigned (mapped) via Reflection with
Meta information attached
Class returned
*This process should have no side effects in regard normal operations and the object type of the class. To the general application the class should be the same before and after.
Application does "normal" work with the class (assign values, get values, validate information ,etc.)
Class gets passed back in later
Use the values along with meta information to do something
Broken down to the simplest terms, I am basically looking for a way to "Piggy-back" extra information on any arbitrary class instance without special compile-time modification.
I realize this is an odd problem with some odd constraints, but can it be done?
This applies if you need the extra state per type and not instance
Your best bet is to use a custom attribute against the field.
1) So create the attribute:
[AttributeUsage(AttributeTargets.Field)]
public class MyCustomAttribute : Attribute
{
}
2) Decorate the field:
class MyClass
{
[MyCustomAttribute]
private int _myField;
....
}
3) And then in your reflection:
if(fieldInfo.GetCustomAttributes(typeof(MyCustomAttribute), true).Length>0)
{
...
}
If it has got to be in the instance
If data is to be part of the instance then
either instance needs to allow for its storage
state needs to be stored on a separate class like a dictionary
Second approach is the one first coming to mind and straightforward to do. On the first note, one can
Define state as a separate property that can hold info. This is the one you have suggested and you are not happy with.
Inherit from a base class which provides the extra functionality
Create a generic type, e.g. Metadata<T> which will provide such functionality to all types
I tend to like the third which can encapsulate reflecting the type T and creating necessary placeholders for storing extra state. Main problem with this is you cannot pass the type to methods as a parameter. Which seems that the second solution is the most practical.
I'd be inclined to create a dictionary with the object instances as the keys and the metadata as the values. You'd probably need to be careful to ensure that equality is determined with ReferenceEquals() rather than Equals(). You might also need a compound key comprising the object and the relevant PropertyInfo.
This approach also wouldn't work if the metadata needs to follow the object into some context where the metadata dictionary is not available.
It is valid (ie. it compiles and runs) to put an attribute on the generic parameter for a class or a method:
public class MyClass<[My] T>
{
private void MyMethod<[My] T>()
{}
}
public class MyAttribute : Attribute
{}
I've never seen this used, and am struggling to come up with a reason as to why you would want to.
Is it just a quirk/side-effect of the language specification, or is there a valid/useful reason to put an attribute in this position?
For the same reason attributes are useful on any construct; they supply meta-data that can be used by Reflection or other post-processors to do various things. For instance, you might have an AOP system that uses an attribute on a type argument to apply certain run-time constraints that otherwise could not be expressed. I'm not sure if there are any systems that actually use these attributes to do anything, but there's no reason to disallow them as metadata.
I'm sure some AOP nut will find a valid reason to decorate generic parameters with attributes. I certainly can't think of any. Try this:
typeof(MyClass<>).GetGenericArguments().GetCustomAttributes().OfType<MyAttribute>();
If this Enumerable has any elements, then it is possible to access the attribute you placed on the class's generic parameter. If not, then you can't and thus having data you'd expect to access from any other class in your codebase is pointless. HOWEVER, they can still have code that runs when instantiated, and they're instantiated by the runtime when the generic class comes into scope, allowing you to perform aspect-oriented logic in the attribute itself. Exactly what that would be, and how it would be any different than decorating the generic class or method directly, is left as an exercise to people who worship AOP far more than I do.
Using Protobuf-Net, I see that it does not seem possible to deserialize a class without having a parameterless constructor or I may be missing something?
I don't want some of the classes with a parameterless constructor. Is there some kind of attributes that I could use or some other technique?
protobuf-net depends currently on having a parameterless constructor to work.
However that constructor need not be public (it will use reflection if need be to invoke it) so you may be able to define the required private constructor just for use by protobuf-net (adding a comment as to why) and deal with specific serialization related issues there.
This keeps the rest of your api from being able to construct 'illegal' instances.
Marc points out that if you are talking about the outermost message object, you could also create the object yourself and call Serializer.Merge. But if it needs to create an object (because it currently has a null instance, or for new items in a list/array), then it looks for a default constructor.
ShuggyCoUk is right about it using the parameterless constructor.
Just for completeness, though - if you are talking about the outermost message object, you could also create the object yourself and call Serializer.Merge. But if it needs to create an object (because it currently has a null instance, or for new items in a list/array), then it looks for a default constructor.
I suppose that I could also provide some markup in the attribute to say "just create a raw object via FormatterServices", but this feels unnecessary (compared with a private parameterless constructor), and may not work on all platforms (Silverlight, CF, etc - being likely problems).
Greetings,
I have a particular object which can be constructed from a file, as such:
public class ConfigObj
{
public ConfigObj(string loadPath)
{
//load object using .Net's supplied Serialization library
//resulting in a ConfigObj object
ConfigObj deserializedObj = VoodooLoadFunction(loadpath);
//the line below won't compile
this = thisIsMyObj;
}
}
I want to, in essense, say "ok, and now this object we've just deserialized, this is the object that we in fact are." There are a few ways of doing this, and I'm wondering which is considered a best-practice. My ideas are:
Build a copy-into-me function which copies the object field by field. This is the current implementation and I'm pretty sure its a horrible idea since whenever a new member is added to the object I need to also remember to add it to the 'copy-into-me' function, and there's no way that's maintainable.
Build a static method for the ConfigObj class which acts as a de-facto constructor for loading the object. This sounds much better but not very best-practice-y.
I'm not entirely happy with either of the two, though. What is the acknowledged best practice here?
Your second option is what is called a factory method and is a common design technique. If you do use this technique, you may find that you need to know the type of class you will load before you actually load the class. If you run into this situation, you can use a higher level type of factory that looks at the stream and calls the factory method for the appropriate type of class.
There's nothing wrong with having a static method instead of a constructor. In fact, it has a number of advantages.
I always go with the static method. Usually it's kind of a hierarchy which is loaded, and therefore only the root object needs the method. And it's not really an unusual approach in the .NET framework (e.g. Graphics.FromImage), so it should be fine with users of your class.
Trying to find some verbose reference on the intricacies of Attributes. Any help would be appreciated.
At this point, I'd specifically like to know what time during runtime does an attribute constructor get ran?
If it's over a class
If it's over a property
If it's over a method
Thanks.
The constructor is invoked when you call GetCustomAttributes() on the type or MemberInfo.
Reading the norm (17.3.2 in the C# 2.0 version) it's unspecified. Only the way to convert from the metatada to an instance is.
So you may need to test on different implementations, because if it isn't specified it's bound to be interpreted differently.
The only thing that you can be sure is that it'll be called before is needed. It's not defined the exact time the constructor will be called.
Anyway, the behaviour is unespecified, so you shouldn't rely on whenever the constructur gets called by the current implementation.
Attribute are decorations that stores metadata or informations about a type.
.Net framework utilizes heavily this kind of information to do additional processing when creating instances.
The attribute is constructed only when asked by some other class, with Type.GetCustomAttributes() for example. So, even you can create your own attributes and then asks for your custom attributes.
public class MyOwnAttribute: Attribute {}
/* at some point in another class */
void CheckIfClassIsDecoratedWithMyOwnAttribute()
{
var instance = new MyClass();
if (instance.GetType().GetCustomAttributes(typeof(MyOwnAttribute)))
{
//do whatever you want
}
}