Answered by:
Attributes How does it work

Question
-
HI, while i am learning atttributes I saw the use of an obsolete attribute on any method it will raise an compile error if required. in the same why how do i control my program and I want to see through console, I tought of doing one way as below example
Consider this custom attribute,
[
AttributeUsage(AttributeTargets.Method | AttributeTargets.Struct,AllowMultiple =
false, Inherited = false)] public class MyAttribute : Attribute{
{
{
}
else{
}
}
}
I am using this custom Attribute My
Class AttribTest
{
[
{
return str;}
static void Main(string[] args){
}
}
What would be the output of the above program.
I am expecting on the console
Permitted to use this App
Hire
but I could able to see only Hire.
Why it so. Is not possible to compare the string passed to the custom attribute with the private string in that class. And even When I keep my control point in the custom attribute class, while the Main method is executing I could not able to see the control passed into the method.
Any one help me how does the custom attribute really work. I could able to understand that we can query the attributes using reflection. But what i wanted is how do i display like above. what is that i am missing.
Thanks
satish kumar p
Tuesday, April 15, 2008 12:21 PM
Answers
-
There is nothing magical about most attributes; it is simply that the compiler and runtime give special meaning to *some* attributes, such as ObsoleteAttribute or PrincipalPermissionAttribute and do extra things for free. But most attributes must be manually inspected by your code.
PrincipalPermissionAttribute is fairly close to what you want - it can ensure that the user has a specific role, but it isn't as flexible as you might like:
[
PrincipalPermission(SecurityAction.Demand, Role="Foo")] public void Bar(){ // only "Foo" users can call this method
}
Depending on what you are trying to do, another option might be something like PostSharp:
This is an AOP framework for .NET that injects functionality via attributes; essentially adding the extra code you want - but it would be just as easy to simply call a static method instead:
public static string SayHello(string str)
{
SomeUtilityClass.CheckReg(str, "a12nf");
return str;
}
Tuesday, April 15, 2008 12:35 PM -
Attributes do not lead to code execution, so, if i understand you well, it is not possible.
By making use of reflection, you can inspect instances (find out which attributes that are applied to them), and decide to execute code.
Code Snippetclass Program
{
static void Main( string[] args )
{
InspectAssembly( Assembly.GetExecutingAssembly() );
Console.Write( "{0}Press any key to continue...", Environment.NewLine );
Console.ReadKey();
}
static void InspectAssembly( Assembly assembly )
{
foreach( Type type in assembly.GetTypes() )
{
foreach( MethodInfo methodInfo in type.GetMethods() )
{
foreach( MyAttribute myAttribute in methodInfo.GetCustomAttributes( typeof( MyAttribute ), true ) )
{
Console.WriteLine( "Type: {0} Method: {1} IsValid: {2}", type.Name, methodInfo.Name, myAttribute.IsValid );
}
}
}
}
}
class Foo
{
public Foo()
{
Console.WriteLine( "running constructor for Foo" );
}
[My( "valid" )]
public void DoSomething()
{
}
[My( "invalid" )]
public void DoAnother()
{
}
}
[AttributeUsage( AttributeTargets.Method )]
class MyAttribute : Attribute
{
private bool isValid;
public MyAttribute( string key )
{
this.isValid = ( key == "valid" );
}
public bool IsValid
{
get { return this.isValid; }
}
}Wednesday, April 16, 2008 6:12 AM -
The compiler verifies that calling the constructor with the parameters, and setting the properties with the values would work, and then serializes out the data to the metadata contained in your assembly. It does not, at compile-time execute any code in your attribute at all.
At runtime, you can use reflection to look at a class, property, or whatever, and ask to get back the attributes for it, and at that point, the constructor code and property code will be executed.
Basically, attributes do not execute any code at compile time, they are only stored in the assembly.Wednesday, April 16, 2008 7:25 AM
All replies
-
There is nothing magical about most attributes; it is simply that the compiler and runtime give special meaning to *some* attributes, such as ObsoleteAttribute or PrincipalPermissionAttribute and do extra things for free. But most attributes must be manually inspected by your code.
PrincipalPermissionAttribute is fairly close to what you want - it can ensure that the user has a specific role, but it isn't as flexible as you might like:
[
PrincipalPermission(SecurityAction.Demand, Role="Foo")] public void Bar(){ // only "Foo" users can call this method
}
Depending on what you are trying to do, another option might be something like PostSharp:
This is an AOP framework for .NET that injects functionality via attributes; essentially adding the extra code you want - but it would be just as easy to simply call a static method instead:
public static string SayHello(string str)
{
SomeUtilityClass.CheckReg(str, "a12nf");
return str;
}
Tuesday, April 15, 2008 12:35 PM -
Hi
Thanks for the reply, I got some a lot of useful information from your post .No doubt Postsharp is useful, My question is without using postsharp can't we achieve the same however I am just looking for a simple thing like when I pass any string to the attribute constructor, and if the string value passed is equal to some thing I just want to display a message using a console this is what I just required.
regards
satish
Wednesday, April 16, 2008 5:48 AM -
Attributes do not lead to code execution, so, if i understand you well, it is not possible.
By making use of reflection, you can inspect instances (find out which attributes that are applied to them), and decide to execute code.
Code Snippetclass Program
{
static void Main( string[] args )
{
InspectAssembly( Assembly.GetExecutingAssembly() );
Console.Write( "{0}Press any key to continue...", Environment.NewLine );
Console.ReadKey();
}
static void InspectAssembly( Assembly assembly )
{
foreach( Type type in assembly.GetTypes() )
{
foreach( MethodInfo methodInfo in type.GetMethods() )
{
foreach( MyAttribute myAttribute in methodInfo.GetCustomAttributes( typeof( MyAttribute ), true ) )
{
Console.WriteLine( "Type: {0} Method: {1} IsValid: {2}", type.Name, methodInfo.Name, myAttribute.IsValid );
}
}
}
}
}
class Foo
{
public Foo()
{
Console.WriteLine( "running constructor for Foo" );
}
[My( "valid" )]
public void DoSomething()
{
}
[My( "invalid" )]
public void DoAnother()
{
}
}
[AttributeUsage( AttributeTargets.Method )]
class MyAttribute : Attribute
{
private bool isValid;
public MyAttribute( string key )
{
this.isValid = ( key == "valid" );
}
public bool IsValid
{
get { return this.isValid; }
}
}Wednesday, April 16, 2008 6:12 AM -
Hi timvw,
Thanks for the reply, i came too understand that from your reply that we can check the attributes usage only using reflection we can check some if conditions too in custom attribute however they result of the if condition can be viewed only using reflection.
But what is the case like when I want say to the user that method is not worth using, like if in the case of obsolete. how do i implement such custom attributes, which will indicate some message at the time of compilation to the developer,
regards
satish
Wednesday, April 16, 2008 6:40 AM -
The compiler verifies that calling the constructor with the parameters, and setting the properties with the values would work, and then serializes out the data to the metadata contained in your assembly. It does not, at compile-time execute any code in your attribute at all.
At runtime, you can use reflection to look at a class, property, or whatever, and ask to get back the attributes for it, and at that point, the constructor code and property code will be executed.
Basically, attributes do not execute any code at compile time, they are only stored in the assembly.Wednesday, April 16, 2008 7:25 AM