How Does the C# Compiler Detect Com Types

How does the C# compiler detect COM types?

By no means am I an expert in this, but I stumbled recently on what I think you want: the CoClass attribute class.

[System.Runtime.InteropServices.CoClass(typeof(Test))]
public interface Dummy { }

A coclass supplies concrete
implementation(s) of one or more
interfaces. In COM, such concrete
implementations can be written in any
programming language that supports COM
component development, e.g. Delphi,
C++, Visual Basic, etc.

See my answer to a similar question about the Microsoft Speech API, where you're able to "instantiate" the interface SpVoice (but really, you're instantiating SPVoiceClass).

[CoClass(typeof(SpVoiceClass))]
public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }

For what collection types does the C# compiler generate collection classes?

Short answer: use the most appropriate generic type that expresses your intent. Queue<T> is just fine if you want to represent a queue, for example.


Longer answer: quite honestly: that documentation is vague. When it mentions "the compiler", it isn't talking about the C# (build-time) compiler (which translates C# to IL), but rather to the JIT (runtime) compiler, which translates IL to CPU instructions (appropriately for your specific CPU and environment).

The feature it is using here is simply a feature of generics, which applies equally to any generic usage; it isn't specific to List<T> - the same ideas apply to any <T> type (or multi-generic-parameter types, too), including arrays.

The docs are also ... a little wooly and imprecise. The details probably don't really matter to most people, but it doesn't really do this per-T; or at least, not all T. Every value-type T (or permutation involving value-types, for multi-generic-parameter scenarios) gets a bespoke JIT, but all the reference-type T share a single implementation. This is tied to the fact that only value-type usages involve boxing, and that boxing is per-T; for reference-type usages, a type check is sufficient. And even for value-type scenarios, often the box step can be avoided via "constrained" calls.


If I was trying to be generous: the document is perhaps trying to contrast against non-generic collections (which you shouldn't really be using in %current year%), in a way that might make sense to someone more familiar with .NET 1.1; in doing so, they're... very far from precise.

How to check if Class is Compiler Generated

Assuming that Microsoft follows their own guidance for application of the System.Runtime.CompilerServices.CompilerGeneratedAttribute,

Remarks

Apply the CompilerGeneratedAttribute attribute to any application
element to indicate that the element is generated by a compiler.

Use the CompilerGeneratedAttribute attribute to determine whether an
element is added by a compiler or authored directly in source code.

you can check the type's CustomAttributes to determine if the type is so decorated with something like this:

using System.Reflection;

public bool IsCompilerGenerated(Type type)
{
return type.GetCustomAttribute<System.Runtime.CompilerServices.CompilerGeneratedAttribute>() != null;
}

Does compile-time type still exist at runtime?

Is the compile-time type Animal being the type of the variable a on the stack?

Yes (although saying on the stack is unnecessary - whether it is on the stack or not is irrelevant).

Check the IL for the code at SharpLab:

using System;
using System.Reflection;

public class Animal{}

public class Dog: Animal {}

public class Program
{

public static void Main()
{
Animal a = new Dog();

ShowType(a);

MethodInfo mi = typeof(Program).GetMethod("Main");
MethodBody mb = mi.GetMethodBody();

foreach (LocalVariableInfo lvi in mb.LocalVariables)
{
Console.WriteLine("Local variable: {0}", lvi.LocalType);
}
}

public static void ShowType<T>(T o)
{
Console.WriteLine(typeof(T)); // Animal
Console.WriteLine(o.GetType()); // Dog
}
}

Note, in particular:

.locals init (
[0] class Animal a
)

which clearly shows that the type of the variable is Animal (which is no surprise, it will always be consistent with the code).

Note also that reflection (at runtime) outputs Animal (not Dog). So clearly the metadata of the method is storing the variable type.

Checking object's compile-time type in C#

I'm not sure what the rules of your assignment were, but if you have a virtual method in the base class and override it in the derived, you are always going to get "B".

If you are allowed to change the inheritance on the types you can do this:

public class Program
{
public static void Main()
{
A m1 = new B();
B m2 = new B();

Console.Write("m1: ");
m1.Fun();
Console.Write("m2: ");
m2.Fun();

// m1: A
// m2: B
}
}

abstract class A
{
public void Fun() => Console.WriteLine("A");
}

class B : A
{
public new void Fun() => Console.WriteLine("B");
}


Related Topics



Leave a reply



Submit