I saw this in saample source code project.
[Input]
public int Length { get; set; }
It was defined in a class:
namespace PowerLanguage.Strategy
{
public class MovAvg_Cross_SE : SignalObject
{
....
What does the [input] mean?
That's an Attribute -- a way to declare information about your source code. What your particular attribute means depends on the namespace of the attribute. You can hover over it to get information on it or (if the declaration is part of your project) ctrl-click on it to see its source.
Its an attribute. The full class name is InputAttribute. Code can reflect over properties and discover attributes, which may modify the behavior or trigger other functionality. Another example of adding functionality is Data Annotations, which when used with something that will discover and run them, can be thought of as adding behavior. You can read more about attributes here (while older, the concept is the same).
Related
I've seen the term "Buddy class" used as an 'answer' to questions like "how can I add annotations to a partial class in another file" but these answers assume I know what a Buddy Class is, and the code examples assume I understand how/why this works.
I couldn't see a simple explanation of what a buddy class in C# is, and how/why it allows me to modify an existing class such as adding annotations to properties.
‘Buddy class’ is not necessarily C# specific but I believe it is more commonly seen in .Net as its sort of a pattern, or technique (hack), used to extend auto generated classes and add attributes to them.
They are also referred to as associated classes sometimes, or meta data classes. The naming convention is to append MD (for meta data) to the buddy class so it can be identified as one. As for why, well- auto generated code will overwrite any changes you make. Associated classes could be a way to circumvent that, and you could keep your custom meta data (for example validation attributes).
You have one class that is auto generated, handily marked as partial (I believe that is actually why the partial modifier was introduced- to extend auto generated classes).
You want to apply an attribute so you create a separate class that contains that, and you buddy it up with the other class.
If VS generates this for one of your entitites:
public partial class AutoGeneratedClass
{
public string SomeData { get; set; }
}
And you want to extend that and add custom meta data you could create this:
[MetadataType(typeof(NotAutoGeneratedClassMD))]
public partial class AutoGeneratedClass
{
}
public class NotAutoGeneratedClassMD
{
[DisplayName("This is some data")]
public string SomeData { get; set; }
}
Short version:
What: Way to associate classes to extend an auto generated class with custom meta data
Why: Avoid having your changes to an auto generated class be overwritten when generated again.
Personally I'm not a fan, but that is a different story :)
I have a class like below, auto generated by Entity Framework, based in our database:
public partial class TB_Cliente
{
public int IDCliente { get; set; }
public string Nome { get; set; }
// other properties
}
I'm using DataContractJsonSerializer and I need to change the properties' names in serialization. For instance, the property IDCliente must be serialized like ClientID.
I can't use [DataMember] in top of the property, because the class is auto generated, and any future changes will generate the class again and these changes will be lost.
I've had the same problem in the past, when I wanted to use data annotations. I've found the below solution, creating another file and using an interface, which works perfectly:
public interface ITB_Cliente
{
[Required]
string Nome { get; set; }
// other properties
}
[MetadataType(typeof(ITB_Cliente))]
public partial class TB_Cliente : ITB_Cliente
{
}
But this solution doesn't help me now, because (as far as I know) this attribute must be set directly in the class. I've tried to set it in the interface and it didn't work.
Is there a way to change the properties' names in the serialization, in my case? Any help will be greatly appreciated.
You probably want to use DTOs for serialization. I have not tried but AutoMapper can probably do the heavy lifting for you.
I have been trying to overcome a similar problem this week for JSON output from some legacy VB.Net classes that I would prefer not to change if I can avoid it. The serialisation is returning underlying private member names rather than the public property names, e.g. "mFirstName".
Also for autogenerated property names I am getting json like
{"k__BackingField":"Brian","k__BackingField":"Furlong"}
which is not good.
I considered a similar approach to Pawel's above (create DTOs and use Automapper which I have used extensively before).
I am also checking to see if I can make a customised json serialiser but haven't got very far yet.
The third way I have investigated is to create an "Aspect" using PostSharp which will decorate the business entity classes with the DataContract.
This would allow me to create the necessary [DataContract] and [DataMember] attributes on the public properties at compile time without having to modify the legacy code base. As I am using the legacy assemblies within a new WebAPI assembly it effectively extends the code for me.
For guidance / hints please refer to the following links:
For background information http://pietschsoft.com/post/2008/02/NET-35-JSON-Serialization-using-the-DataContractJsonSerializer
For the question that gave the pointer: How to inject an attribute using a PostSharp attribute?
For a walkthrough on how to do something similar which is enough to get going on this: http://www.postsharp.net/blog/post/PostSharp-Principals-Day-12-e28093-Aspect-Providers-e28093-Part-1
My issue is with Dotfuscator configuration for renaming. Imagine a class that would look like this:
Class MyClass
{
private int _propertyA;
private int _propertyB;
public int PropertyA
{
get{return _propertyA;}
set{_propertyA = value;}
}
[Obfuscation(Feature = "renaming", Exclude = true)]
public int DestinationReference
{
get{return _propertyB;}
}
}
The obfuscated class will be written into someting like this
Class a
{
int s()
void z(int a)
public int DestinationReference
{
get{return _propertyB;}
}
}
This is my assumption from what I can see using .Net Reflector
My issue is the following:
- In our code we implemented a method that look for all attributes of a class using reflection in order to find specific parameters
- This method does not work in the obfuscated code as my accessor PropertyA, has been replaced with two distinct methods for the get accessor and set accessor.
- I know that if I exclude an accessor from renaming it stays an accessor in the msil code and will be found by my method that looks for accessors
My question is:
- Is not renaming the only option?
- Is there a parameter in Dotfuscator that would allow renaming of the accessor without splitting it into two distinct methods and loosing the accessor?
I'm pretty new to obfuscation so pardon my imperfections, this is what I can see for a class similar to the one described above in reflector.
As you can see the property that is excluded from renaming stays a property with a get accessor. But for the other one that got obfuscated I can see two distinct methods s and z
I'm trying to see if there would be a way of obtaining a single accessor, renamed "s" for example with the underlying getter and setter
I found some answers to my question, first after looking at this article : http://vicky4147.wordpress.com/2007/10/23/exploring-msil-properties/
I see that MSIL generates get_XXX() method and set_XXX(int) methods as well as adding a property. Dotfuscator is responsible for renaming the get and set methods (which is what we want) but also for removing the property itself (which I do not want)
A solution is to enable "Library mode" for the obfuscated DLL, if library mode is enabled, the documentation states that:
Names of public classes and nested public classes are not renamed. Members (fields and methods) of these classes are also not renamed if they have public, family, or famorassem access.
In addition, no virtual methods are renamed, regardless of access specifier. This allows clients of your library to override private virtual methods if need be (this is allowed behavior in the .NET architecture).
Any user-specified custom renaming exclusions are applied in addition to the exclusions implied by the above rules.
Property and Event metadata are always preserved.
And this can be seen after obfuscation in reflector, at the top library mode is disabled, at the bottom library mode is enabled
As it can be seen, none of the public classes/methods/fields have been renamed, and more important to me the Property metadata has been preserved.
Now my next question would be, how to preserve the property metadata but allow the renaming of the property itself. I would like to find a solution that is satisfying without having to define manually decorate each properties with custom obfuscation attributes.
I'll keep searching for another day and if I can't find anything will mark this answer as solution to the issue.
I need to hide few methods inside a class based on the parameter that is passed to the constructor in c#. How would I do this?
Thanks in advance!
More Info:
I was part of this GUI development where they had a API with access to registers in a hardware. Now they are releasing a newer hardware so I need to support both old and new one which has a newer API(Mostly duplicate of old one with some old removed and some new registers added).
Moreover, I need to keep this only one class called "API" as we used it in many places. So the idea of using a newer API with a different name was ruled out.
Now finally, I got this idea of including the newer one into old one with just conditionally hiding the registry access methods.
You can't toggle the visibility of members..... the best bet is to have different interfaces that hide the members.
public interface IName
{
string Name { get; set; }
}
public interface INumber
{
string PhoneNumber { get; set; }
}
public class Worker : IName, INumber
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
So either use Worker through the IName or the INumber interface and it will hide the other members on the class....
I think you might be looking at a re-factor here. Try making a base class with all the methods / properties that behave the same regardless of the parameter, then two child classes which behave differently. Also have a look at the class factory pattern.
You will need to restructure the code into multiple classes or interfaces. You can't dynamically change the visibility level of class members based on a parameter value. Members are construction time information not run time.
You can't change visibility of methods, but you can pass parameter to the single method and do some logic depending on your parameter by using switch - case. But it depends on your method structure.
Try to review your class and change its design. Maybe you can find any design pattern that will help you.
You may actually do something alike using Dynamic code generation, although this is more like a hack than actual code that should be used in production.
Maybe if you explain why you need this then you may get more relevant answers.
My searches keep turning up only guides explaining how to use and apply attributes to a class. I want to learn how to create my own attribute classes and the mechanics of how they work.
How are attribute classes instantiated? Are they instantiated when the class they are applied to is instantiated? Is one instantiated for each class instantiated that it is applied to? E.g. if I apply the SerializableAttribute class to a MyData class, and I instantiate 5 MyData instances, will there be 5 instances of the SerializbleAttribute class created behind the scenes? Or is there just one instance shared between all of them?
How do attribute class instances access the class they are associated with? How does a SerializableAttribute class access the class it is applied to so that it can serialize it's data? Does it have some sort of SerializableAttribute.ThisIsTheInstanceIAmAppliedTo property? :) Or does it work in the reverse direction that whenever I serialize something, the Serialize function I pass the MyClass instance to will reflectively go through the Attributes and find the SerialiableAttribute instance?
I haven't use attributes in my day-to-day work before, but I have read about them.
Also I have done some tests, to back up what I'll say here. If I'm wrong in any place - feel free to tell me this :)
From what I know, attributes are not acting as regular classes. They aren't instantiated when you create an object that they are applied to, not one static instance, not 1 per each instance of the object.
Neither do they access the class that they are applied to..
Instead they act like properties (attributes? :P ) of the class. Not like the .NET class properties, more like in the "one property of glass is transparency" kind of property. You can check which attributes are applied to a class from reflection, and then act on it accordingly. They are essentially metadata that is attached to the class definition, not the objects of that type.
You can try to get the list of attributes on a class, method, property, etc etc.. When you get the list of these attributes - this is where they will be instantiated. Then you can act on the data within these attributes.
E.g. the Linq tables, properties have attributes on them that define which table/column they refer to. But these classes don't use these attributes. Instead, the DataContext will check the attributes of these objects when it will convert linq expression trees to SQL code.
Now for some real examples.. I've ran these in LinqPad, so don't worry about the strange Dump() method. I've replaced it with Console.WriteLine to make the code easier to understand for the people who don't know about it :)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
The console result of this method is:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
And the Attribute.GetCustomAttributes(test.GetType()) returns this array:
(the table shows all available columns for all entries.. So no, the Serializable attribute does not have these properties :) )
Got any more questions? Feel free to ask!
UPD:
I've seen you ask a question: why use them?
As an example I'll tell you about the XML-RPC.NET library.
You create your XML-RPC service class, with methods that will represent the xml-rpc methods. The main thing right now is: in XmlRpc the method names can have some special characters, like dots. So, you can have a flexlabs.ProcessTask() xml rpc method.
You would define this class as follows:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
This allows me to name the method in the way I like it, while still using the public name as it has to be.
Attributes are essentially meta data that can be attached to various pieces of your code. This meta data can then be interogate and affect the behaviour of certain opperations.
Attributes can be applied to almost every aspect of your code. For example, attributes can be associated at the Assembly level, like the AssemblyVersion and AssemblyFileVersion attributes, which govern the version numbers associated with the assembly.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Then the Serializable attribute for example can be applied to a type declaration to flag the type as supporting serialization. In fact this attribute has special meaning within the CLR and is actually stored as a special directive directly on the type in the IL, this is optimized to be stored as a bit flag which can be processed much more efficiently, there are a few attributes on this nature, which are known as pseudo custom attributes.
Still other attributes can be applied to methods, properties, fields, enums, return values etc. You can get an idea of the possible targets an attribute can be applied to by looking at this link
http://msdn.microsoft.com/en-us/library/system.attributetargets(VS.90).aspx
Further to this, you can define your own custom attributes which can then be applied to the applicable targets that your attributes are intended for. Then at runtime your code could reflect on the values contained in the custom attributes and take appropriate actions.
For a rather naive example, and this is just for the sake of example :)
You might want to write a persistence engine that will automatically map Classes to tables in your database and map the properties of the Class to table columns. You could start with defining two custom attributes
TableMappingAttribute
ColumnMappingAttribute
Which you can then apply to your classes, as an example we have a Person class
[TableMapping("People")]
public class Person
{
[ColumnMapping("fname")]
public string FirstName {get; set;}
[ColumnMapping("lname")]
public string LastName {get; set;}
}
When this compiles, other than the fact that the compiler emits the additional meta data defined by the custom attributes, little else is impacted. However you can now write a PersistanceManager that can dynamically inspect the attributes of an instance of the Person class and insert the data into the People table, mapping the data in the FirstName property to the fname column and the LastName property to the lname column.
As to your question regarding the instances of the attributes, the instance of the attribute is not created for each instance of your Class. All instances of People will share the same instance of the TableMappingAttribute and ColumnMappingAttributes. In fact, the attribute instances are only created when you actually query for the attributes the first time.
Yes they're instantiated with the parameters you give it.
The attribute does not "access" the class. The attribute is attached to the class' / property's attribute list in the reflection data.
[Serializable]
public class MyFancyClass
{ ... }
// Somewhere Else:
public void function()
{
Type t = typeof(MyFancyClass);
var attributes = t.GetCustomAttributes(true);
if (attributes.Count(p => p is SerializableAttribute) > 0)
{
// This class is serializable, let's do something with it!
}
}
Think of attributes are post-its that are attached to the classes or method definitions (embedded in the assembly metadata).
You can then have a processor/runner/inspector module that accepts these types by reflecting, looks for these post-its and handles them differently. This is called declarative programming. You declare some behavior instead of writing code for them in the type.
Serializable attribute on a type declares that it is built to be serialized. The XmlSerializer can then accept an object of this class and do the needful. You mark the methods that need to be serialized/hidden with the right post-its.
another example would the NUnit. The NUnit runner looks at the [TestFixture] attributes all classes defined in the target assembly to identify test classes. It then looks for methods marked with [Test] attribute to identify the tests, which it then runs and displays the results.
You may want to run through this tutorial at MSDN which has most of your questions answered along with an example at the end. Although they could have extracted a method called
Audit(Type anyType); instead of duplicating that code. The example 'prints information' by inspecting attributes.. but you could do anything in the same vein.
If you take an eye out this downloadable open source code LINQ to Active Directory (CodePlex), you might find interesting the mechanism of the Attributes.cs file where Bart De Smet has written all of his attributes classes definitions. I have learned attributes there.
In short, you may specialize the Attribute class and code some specialized properties for your needs.
public class MyOwnAttributeClass : Attribute {
public MyOwnAttributeClass() {
}
public MyOwnAttributeClass(string myName) {
MyName = myName;
}
public string MyName { get; set; }
}
and then, you may use it wherever MyOwnAttributeClass gets useful. It might either be over a class definition or a property definition.
[MyOwnAttributeClass("MyCustomerName")]
public class Customer {
[MyOwnAttributeClass("MyCustomerNameProperty")]
public string CustomerName { get; set; }
}
Then, you can get it through reflection like so:
Attribute[] attributes = typeof(Customer).GetCustomAttribute(typeof(MyOwnAttributeClass));
Consider that the attribute you put between square brackets is always the constructor of your attribute. So, if you want to have a parameterized attribute, you need to code your constructor as such.
This code is provided as is, and may not compile. Its purpose is to give you an idea on how it works.
Indeed, you generally want to have a different attribute class for a class than for a property.
Hope this helps!
Not much time to give you a fuller answer, but you can find the Attributes that have been applied to a value using Reflection. As for creating them, you inherit from the Attribute Class and work from there - and the values that you supply with an attribute are passed to the Attribute class's constructor.
It's been a while, as you might be able to tell...
Martin