Object creation in C# question - c#

I'm going over some c# tutorial that states the following:
"After it finds the attribute class, the compiler will check whether the attribute is allowed on a class. Then it will check for a constructor that matches the parameters specified in the attribute use. If it finds one, it creates an instance of the object by calling the constructor with the specified values"
The name of this paragraph is "compilation process", and it refers to the way the compiler handles attributes. I'm sorry for the ignorance, but shouldn't instances be created at run time?
Thanks.

Attributes define metadata for classes -- every instance of the class (i.e. object) will share the same attribute values. This metadata is stored alongside the type definition, which is calculated once at compile time from the source files.

Since there are attributes that also affect the compiler, I wouldn't be surprised if the compiler did instantiate them when compiling. So what?

There is a "compilation" process that generates an intermediary code which is interpreted using .NET framework.
That's why they are talking about compilation process.

The compiler only creates metadata which describes the attribute construction and assignments to its properties.
The attribute itself is only instantiated at the time you use reflection to list attributes. I think each call to reflection creates a new instance of that attribute.
And I think there is a way(related to reflection only contexts) to check the attribute directly from the meta without instantiating it at all.

Related

Will the C# attributes affect C# execution or the output?

Syntactically I understand how C# attributes are applied (i.e. denoted in square brackets []). But it is not obvious what effects adding attributes actually has.
For instance:
Are attributes meant to be a type of commenting?
How are these attributes handled by the C# compiler?
Will these C# attributes change the C# program execution in any way?
Attributes are not comments; they are classes that get added to the metadata of "things" in C#. By "things" I mean classes, properties, methods, etc.
An attribute absolutely can change the execution of a program... if something uses Reflection to read and act on the attributes. For example; the [DataMember] attribute will allow a DataContractSerializer to include that member in a serialized object. The [Export] attribute will be picked up by MEF code as a plugin.
There are many other examples and you can also create your own.
For far more information about attributes see: Attributes in C#
Attributes are a powerful construct that can indirectly affect the code execution. You can inspect self or other classes using Reflection and change behaviour based on the presence of certain attributes.
Take a look at the c# programming guide: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/

Access PropertyInfo via metadata token for use from IL?

I have an application where I have a method taking a PropertyInfo parameter and would like to call this method from IL. For similar methods taking a MethodInfo, for example, I can create an intermediate method taking a RuntimeMethodHandle and use GetMethodFromHandle. The IL can then use Ldtoken to pass the handle.
However, there does not appear to be an equivalent metadata token for properties. I can see why this might be the case (since properties are really just a way of bundling methods together and never 'called' from IL), but there is definitely property metadata associated with the type. I have access to this property metadata at Emit-time, so I'd like a way to be able to pass this directly without having to resort to Reflection by name at runtime (i.e. emit Reflection calls to GetProperty taking a string that will execute at runtime.) Is there a way to do this?
Per a request in the comments, here is the application:
I'm creating an adaptor class that exposes a property reference as its component bits via a bool this[int index] property. My application compiles PLC code to a .NET assembly and so I'm trying to create diagnostic accessors that approximate the easy bitwise access provided by the PLC (where you write MyTag.2 to indicate bit 2 of tag MyTag.) This syntax can't be used for consumption by C#, but PLC.GetBits().MyTag[2] is a reasonable approximation.
My original approach was implemented using PropertyInfo (which is how I encountered this issue), but I can certainly work around it by passing the applicable metadata from the PropertyInfo as multiple parameters. I was mainly just curious to see if it was possible to pass the PropertyInfo directly, since I hadn't ever run into this before.
No, I don't think you can. I say this in part through familiarity with that API, and in part because the Expression compiler in the C# compiler still uses reflection when it refers to a PropertyInfo, but uses more direct methods (ldtoken etc) when referring to types and methods (for example, a getter/setter). I suspect the C# compiler team would have used it if it existed.
However, in most common IL-emit scenarios, it is not necessary to pass around a PropertyInfo. options:
use MethodBase to get the getter or setter (methods can be fetched by token), and infer the property by name (not 100% robust, but should usually work)
pass around the name instead (ldstr)
Refer to Ecma-335, Partition I, 8.10.3 Property and event inheritance
Fundamentally, properties and events are constructs of the metadata intended for use by tools
that target the CLI and are not directly supported by the VES itself. Therefore, it is the job of the
source language compiler and the reflection library (see Partition IV – Kernel Package) to
determine rules for name hiding, inheritance, and so forth. The source compiler shall generate
CIL that directly accesses the methods named by the events and properties, not the events or
properties themselves.
Ecma-335, Partition I, 8.11.3 Property definitions
A property definition is always part of either an interface definition or a class definition. The
name and value of a property definition is scoped to the type that includes the property
definition. The CTS requires that the method contracts that comprise the property shall match the
method implementations, as with any other method contract. There are no CIL instructions
associated with properties, just metadata.

When are Attribute Objects created?

Since Attributes are really just Metadata attached to assemblies, does that mean that Attribute Objects are only created on request (such as when you call GetCustomAttributes)?
Or are they created on creation of the object?
Or, a combination of the first 2, created when the object is created due to attribute scanning by the CLR?
From CLR via C#, third edition:
If you want to construct an attribute object, you must call either GetCustomAttributes or
GetCustomAttribute. Every time one of these methods is called, it constructs new instances
of the specified attribute type and sets each of the instance’s fields and properties based on the values specified in the source code. These methods return references to fully constructed instances of the applied attribute classes.
So yes, they are only created on request.
They are created on request.
For example, if you add some .NET 3.0 attributes to a .NET 2.0 Assembly (e.g. WCF DataContractAttribute), you'll still be able to use the .NET 2.0 Assembly on a machine that doesn't have .NET 3.0 installed, provided you don't have any code that attempts to access the attributes.
It is not quite that clean, attributes also affect code generation. Some attributes are interpreted by the compiler, [DllImport] for example. Some are discovered by the jitter, [MethodImpl] for example. This is infinitely extended to other tools and classes in the framework that were written to take advantage of attributes.
But these tools are just doing what you need to do if you want to find your own attributes, calling GetCustomAttributes() is required. That kind of code is never associated with an instance of the object, attributes apply to types.

Attributes, just metadata or needed?

Few days ago I asked what this attribute means:
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")] public unsafe static extern bool ZeroMemory(byte* destination, int length);
I have learned that attributes are metadata but what I do not understand is - is this needed in this case? I thought metada are just that, metadata that can be ommited. Also the code seems to be running fine when I remove the attibute.
I would like to understand.
PS: Hans Passant mentioned its covered by any book about .NET Csharp..it is not, the largely used one VS 2010 from John Sharp does not cover it.
The metadata does usually have a reason and a meaning. In this particular case it tells the compiler how to bind this external method definition (e.g. to which DLL import it matches).
Other attributes control how interop is performed by the framework, yet other control how the object inspector displays data. 3rd-party attributes are also used extensively to control various behaviors, for instance for finding specific type information when performing reflection.
No, this attribute is absolutely required. It informs the CLR that what you've defined actually uses platform invokation services (or, P/Invoke) to call a function defined in unmanaged code.
Specifically, the RtlZeroMemory function, defined in the library kernel32.dll.
Without it, the compiler wouldn't know which function it was bound to, and the CLR wouldn't know which function to call at run-time.
This attribute is doing 2 things
Informs the CLR that the C method being invoked lives in kernel32.dll
Informs the CLR that the C method name is RtlZeroMemory and not ZeroMemory as it's named in code.
Yes this attribute is 100% necessary. It's a requirement for any PInvoke method to at the least name the DLL the C method lives in.
As your example shows, attributes are in fact needed in several key areas of .NET programming.
Attributes provide a model known as "Aspect-Oriented Programming" or AOP. Instead of having to write code that performs some specific task, such as serialization, DLL interop, logging, etc, you can instead simply decorate the classes or members on which you want these tasks performed with an attribute. Attributes are a special type of class, with members which can be invoked by the CLR as it runs your code, that will perform the task you wanted when you decorated the code.
You are correct in part; many attributes are intended simply to store metadata. DescriptionAttribute is a good one. However, even in this case, the attribute is important depending on how it's used. If you are decorating a member of a GUI class that you want to use in the designer, [Description()] provides valuable information to the user of the class in the designer, which may not be you. I've also seen and used many alternate uses for DescriptionAttribute; it can be applied to almost anything, so I've used it to provide "friendly names" for Enum constants, coupled with a GetDescription() extension method to grab them, when using Enums to populate drop-down lists.
So, while it's technically "metadata", an attribute's being "required" is governed by how much you want the task inherent in that attribute to be performed.
As for this particular attribute, I'm not too sure. To be honest, I've never seen it in almost a year of constant C#.
However, attributes in general can prove very useful. For instance, I was having issues with the VS2010 designer setting autocomplete properties in the wrong order, and getting run-time errors as a result. The solution was to add attributes to the autocomplete properties that prevented the designer from writing these properties to the design file, and instead setting the properties myself in the .cs file (in the proper order).
Summary: Attributes (usually) are not required, but can prove extremely useful.

Is .Net attribute feature used at compile-time or run-time or both?

In .Net, is the attribute feature used at compile-time or run-time or both? Can you give me some examples?
Most are used at runtime only. A very limited number are used by the compiler, including:
[Conditional(...)] - omit method calls per build symbols
[Obsolete(...)] - emit a warning/error as build output
[Serializable] - gets written as a CLI flag
[Extension] - used for extension methods
[AttributeUsage] - affects how attributes are applied
-
There are a range of things like [AssemblyVersion], [AssemblyFileVersion] etc that are used by the compiler when creating the assembly file, and things like [InternalsVisibleTo] which affect accessibility.
Additionally, tools like PostSharp do extra post-compile steps based on attributes.
There are some other attributes that the compiler may add to generated types/methods (for anon-methods / types, iterator blocks, etc).
Attributes are output as metadata to the assembly at compile time. This meta data is then used at runtime via reflection - for example using GetCustomAttributes().
Some attributes are used by the compiler at compile time, too. For example the compiler looks at the AttributeUsageAttribute to determine if an attribute can be used for a specific object.
Attributes are compiled into the code at compile time, but they are often used at runtime as triggers to do things differently.
The compiler adds what is called metadata to the object that is decorated with an attribute. This metadata, whether created via attributes or otherwise, is all accessible at run-time thru Reflection. Thus, you can decorate with attributes and then read the details when the program is running. However, to say that the metadata is "used" at compile time isn't quite correct, as the compiler doesn't care what metadata there is.

Categories

Resources