Why is not virtual table pointer not included in my decompiled code? - c#

I was reading about virtual method tables on wikipedia and I stumbled upon
Whenever a class defines a virtual function (or method), most compilers add a hidden member variable to the class which points to an array of pointers to (virtual) functions called the virtual method table (VMT or Vtable).
However, when I decompile my test code I don't find any member variable in the IL.
I am using latest version of Roslyn to compile (2.6.0).
Here is my test code:
namespace ConsoleApp1
{
using System;
internal class Program
{
private static void Main(string[] args)
{
var a = new Base();
var b = new Derived();
a.Say();
b.Say();
}
}
public class Base
{
public virtual void Say()
{
Console.WriteLine($"{this.GetType()}");
}
}
public class Derived : Base
{
public override void Say()
{
Console.WriteLine($"{this.GetType()}");
}
}
}
I suppose I am misunderstanding something here, could you help me what it is?

Related

Why does an interface's default implementation get called when two classes are in the inheritance chain, and the class in the middle is empty

Summary
I have found that inserting a class between an interface and another derived class results in the interface's default implementation being called rather than the derived implementation for the same method. This is unexpected behavior. Why is this happening?
Example
I have created a sample project which reproduces the problem:
public interface IPrinterInterface
{
public void PrintIt() => Console.WriteLine("Interface");
}
public class MiddlePrinter : IPrinterInterface{}
public class Printer : MiddlePrinter
{
public void PrintIt() => Console.WriteLine("Class");
}
class Program
{
static void Main(string[] args)
{
var printer = (IPrinterInterface)new Printer();
printer.PrintIt(); // This prints "Interface"
Console.ReadLine(); // so the app sits
}
}
This code results in Interface being printed out.
To contrast, if the MiddlePrinter class is removed from the inheritance (as shown in the following code), then the code prints "Class":
public interface IPrinterInterface
{
public void PrintIt() => Console.WriteLine("Interface");
}
public class Printer : IPrinterInterface
{
public void PrintIt() => Console.WriteLine("Class");
}
class Program
{
static void Main(string[] args)
{
var printer = (IPrinterInterface)new Printer();
printer.PrintIt(); // This prints "Class"
Console.ReadLine(); // so the app sits
}
}
I didn't expect to see this type of behavior, can someone explain why this is happening?
Platform
This has been reproduced in a .NET5 console application and a modern Xamarin Android application.
Classes do not inherit members from interfaces, not even with default implementations. Source.
Note that a class does not inherit members from its interfaces; that is not changed by this feature
As such, since MiddlePrinter does not contain an inherited member for Printer to override, the most concrete implementation of PrintIt() from IPrinterInterface's point of view is its own default implementation.
This is made evident by attempting to apply the override keyword to Printer.PrintIt(). You will get an error that no suitable method was found to override.
Without MiddlePrinter, Printer provides a more concrete implementation by replacing the default.
The reason is that when casting to an interface, it tries to find the first function that is in the same inheritance level as the interface or a lower inheritance level (same or parent class). Because you defined the functionality for the interface (default fallback function) it can't find a suitable function to override and simply reverts to the default function specified in the interface.
For example I've added another printer called Lower printer:
public interface IPrinterInterface
{
// Default function if no parent functions are found.
public void PrintIt() => Console.WriteLine("Interface");
}
public class LowerPrinter
{
public void PrintIt() => Console.WriteLine("Lower");
}
public class MiddlePrinter : LowerPrinter, IPrinterInterface
{
}
public class Printer : MiddlePrinter
{
public void PrintIt() => Console.WriteLine("Class");
}
internal class Program
{
private static void Main(string[] args)
{
var printer = (IPrinterInterface)new Printer();
printer.PrintIt(); // This prints "Lower"
Console.ReadLine(); // so the app sits
}
}
But now if I extend it further:
public class BasePrinter
{
public void PrintIt() => Console.WriteLine("Base");
}
public class LowerPrinter : BasePrinter
{
public void PrintIt() => Console.WriteLine("Lower");
}
It will still print Lower because it is the first suitable function found. The reason it can't search in the children or derived classes is because there is no guarantee the function will in those classes. You might be thinking "but how since they inherit?" - Because if the child class has a function with the same name - it hides the parent method - not implement it.

Discussion about the New keyword for Method Overhiding in C#

I read some material about the "new" keyword for method overhiding in C#. However I still don't see the significant purpose of that "new" keyword except to fix the warning "CS0108 C# hides inherited member. Use the new keyword if hiding was intended." in Visual Studio.
For sample:
class ClassA
{
public void printInfo()
{
Console.WriteLine("I'm A");
}
}
Test Case 1:
class ClassB : ClassA
{
public void printInfo()
{
Console.WriteLine("I'm B");
}
}
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
a.printInfo();
ClassB b = new ClassB();
b.printInfo();
ClassA ab = new ClassB();
ab.printInfo();
Console.ReadKey();
}
}
And
Test Case 2 with "new" keyword:
class ClassB : ClassA
{
public new void printInfo()
{
Console.WriteLine("I'm B");
}
}
class Program
{
static void Main(string[] args)
{
ClassA a = new ClassA();
a.printInfo();
ClassB b = new ClassB();
b.printInfo();
ClassA ab = new ClassB();
ab.printInfo();
Console.ReadKey();
}
}
They both have the same output:
I'm A
I'm B
I'm A
The difference is that "new" keyword fixes the warning.
Could someone show me more samples for the helpfulness of the "new" keyword here ?
There is no difference between both codes. The compiler is simply warning you that you might be unaware of the fact that you are hiding A.printInfo and it's simply drawing your attention to it.
In large codebases where maybe you don't even own A it's easy to write a method in a derived class that has the same signature as an existing method in the base class.
With the keyword new you get three immediate advantages:
You are informing the compiler that you are aware of the fact and you are intentionally hiding a method/property.
You are making it clear to anyone reviewing or mantaining your code in the future that you are hiding a method/property.
Your code actually compiles if warnings are set to be treated as compile time errors, something that is advisable and commonly the case in any decent quality coding environment.
MSDN has a good article about when to use Override and New keywords took a look at it
Knowing When to Use Override and New Keywords
The main idea is that when you are writing public new void function() you are telling the compiler that you know that this method is being hidden by the method from baseclass and the warning is disappearing. Now you will be able to use this method from instance of the derived class and the base method from instance of the base class or boxed to the base class.
Both your samples of code give the same result because the addition of the new modifier doesn't change the output of the compiler - it just gets rid of the compiler warning CS0108. Without the new, the compiler is adding it for you:
This warning informs you that you should use new; the variable is declared as if new had been used in the declaration.
That said, hiding with new and overriding do not have the same effect as each other, due to polymorphism.
Consider the following case (try it online):
Main class:
public class Program
{
public static void Main()
{
Developer developer = new Developer();
PrintSalaryWithHiding(developer);
PrintSalaryWithOverriding(developer);
}
public static void PrintSalaryWithHiding(Employee employee)
{
Console.WriteLine("Salary (with hiding): " + employee.SalaryWithHiding);
}
public static void PrintSalaryWithOverriding(Employee employee)
{
Console.WriteLine("Salary (with overriding): " + employee.SalaryWithOverriding);
}
}
Base class (note that SalaryWithHiding is not virtual but SalaryWithOverriding is):
public abstract class Employee
{
public int SalaryWithHiding
{
get
{
return 10000;
}
}
public virtual int SalaryWithOverriding
{
get
{
return 10000;
}
}
}
Derived class (note the new before SalaryWithHiding and the override before SalaryWithOverriding):
public class Developer : Employee
{
public new int SalaryWithHiding
{
get
{
return 50000;
}
}
public override int SalaryWithOverriding
{
get
{
return 50000;
}
}
}
The result of this is
Salary (with hiding): 10000
Salary (with overriding): 50000
Why?
It's because the new keyword tells the compiler that if you have a instance of a Developer, declared as a Developer, calling the SalaryWithHiding method will call the one in the Developer class instead of the one in the Employee class (i.e. it hides it).
When you have a instance of a Developer, declared as an Employee, calling the SalaryWithHiding method calls the one in the Employee class.
You can see this in the following cut-down example (try it online):
Main class:
public class Program
{
public static void Main()
{
Developer developer = new Developer();
Console.WriteLine("Developer salary when declared as developer: " + developer.SalaryWithHiding);
// these are the same object!
Employee employee = developer;
Console.WriteLine("Developer salary when declared as employee: " + employee.SalaryWithHiding);
}
}
Employee:
public abstract class Employee
{
public int SalaryWithHiding
{
get
{
return 10000;
}
}
}
Developer:
public class Developer : Employee
{
public new int SalaryWithHiding
{
get
{
return 50000;
}
}
}
The result is:
Developer salary when declared as developer: 50000
Developer salary when declared as employee: 10000
Summary
In general, I would say you should only use the new modifier if you know what you are doing, as it breaks polymorphism: as you saw in your own example, when you had
ClassA ab = new ClassB();
ab.printInfo();
it called the method in ClassA as though you hadn't declared a separate method in ClassB which have a different result. That can be very confusing. You would have been much better off making the method in the base virtual and overriding it in the derived class instead, unless you wanted that behaviour for some reason. In my (contrived) example using new to hide a method resulted in an incorrect salary!

C# Alternative to virtual static methods and static sub classes

Whenever I read questions RE this, or a similar topic of static inheritance, the replies are usually that this is not supported (we know that), and the reason is given as being because this is a poor design and there's probably a better way to do it. I'd love to find a better way of doing it so am open to all suggestions - here's what I am trying to do.
I have a class which has no instance data. All the methods are static. Let's call this class BaseStatic. I now want a new static class (well several of course but lets stick to one) which inherits from this static class and adds some new static methods, let's call this SubStatic.
What I want consumers to be able to write is:
SubStatic.MethodFromSub();
and also
SubStatic.MethodFromBase();
I know I could also write:
BaseStatic.MethodFromBase()
explicitly but then consumers have to know which class implements which methods. I can't do this with inheritance because I can't inherit one static class from another. So what's a better way of doing it?
Now, I know I can have these classes as instance classes, and I can define all the methods as static - that will give me the behaviour I described above but leads to other problems, namely:
When I do this:SubStatic.MethodFromBase() the SubStatic static constructor is not called because the method is running in the parent static class (the parent's static constructor is called)
If one of the static parent methods needs to call another method which the sub class can override, I need a virtual static method in the sub class. Which I know I can't have.
So poor design apparently - can anyone help me redo it? I know I can use instance inheritance and take proper use of virtual methods (I've had it working this way) but client code then always has to create an instance (or I suppose some singleton).
This could serve your purpose, though I certainly would include some exception handling and accompany its implementation with a great deal of documentation as to why and how it works.
When the static constructor for Base is run (once) all assemblies that are currently loaded in the app domain are catalogued, selecting the types that derive from Base. Iterating over those, we run the static constructors. It is worth noting though, that this no longer guarantees the cctor for each implementation will be run exactly once, logic would have to be added to each of them to re-make that assertion. Moreover, types that are loaded after the cctor for Base has been run would not be initialized by calls to methods in Base
To simulate virtual methods, use the new keyword to hide the base method. You can call the base method by qualifying it with the declaring class's name (like in class B in the example)
using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace ConsoleApplication6
{
public class Base
{
static Base()
{
Console.WriteLine("Base cctor");
var thisType = typeof (Base);
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes());
var derivations = loadedTypes.Where(thisType.IsAssignableFrom);
foreach(var derivation in derivations)
{
RuntimeHelpers.RunClassConstructor(derivation.TypeHandle);
}
}
public static void Foo()
{
Console.WriteLine("Bar");
}
}
public class A : Base
{
static A()
{
Console.WriteLine("A cctor");
}
}
public class B : Base
{
static B()
{
Console.WriteLine("B cctor");
}
public new static void Foo()
{
Console.WriteLine("Bar!!");
Base.Foo();
}
}
class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}
EDIT
Another option lies in the CRTP (or CRGP in the C# paradigm) or curiously recurring template (generic) parameter pattern
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication6
{
public class Base<T>
where T : Base<T>
{
static Base()
{
RuntimeHelpers.RunClassConstructor(typeof (T).TypeHandle);
}
public static void Foo()
{
Console.WriteLine("Bar");
}
}
public class Base : Base<Base>
{
}
public class A : Base<A>
{
static A()
{
Console.WriteLine("A cctor");
}
}
public class B : Base<B>
{
static B()
{
Console.WriteLine("B cctor");
}
public new static void Foo()
{
Console.WriteLine("Bar!!");
Base<B>.Foo();
}
}
class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}
In this case, when we call a static method on A we're really calling it on Base<A> which is different than Base<B> or Base so we can actually determine how the method was called and run the appropriate cctor.
You can achieve this by using Generics. For example you can use something like that:
public class MainStatic<T> where T : MainStatic<T>
{
public static void Foo()
{
}
static MainStatic()
{
RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
}
}
public class SubStatic : MainStatic<SubStatic>
{
public static void Bar()
{
}
}
public class Instance
{
public void FooBar()
{
SubStatic.Foo();
SubStatic.Bar();
}
}

Get Static Member of Parent Class from Child Inherited Class

Let's say I have,
public class A
{
public static void MyAMethod()
{
}
public class B
{
}
}
public class C : A.B
{
public void MyCMethod()
{
MyAMethod();// I need to call this
}
}
Now I need to call MyAMethod from class C.
Edit: In my situation class A is unavailable. So, I cannot use A.MyAMethod.
You can just call A.MyAMethod() from inside your method since it is static
If you take a look at the IL code for
namespace NestedTest
{
public class A
{
public static void MyAMethod()
{
System.Console.WriteLine("public static void MyAMethod()");
}
public class B
{
public void MyBMethod()
{
MyAMethod();
}
}
}
}
you will find that MyBMethod is implemented(?) as
.method public hidebysig instance void MyBMethod() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: nop
IL_0001: call void NestedTest.A::MyAMethod()
IL_0006: nop
IL_0007: ret
} // end of method B::MyBMethod
As you can see the call to NestedTest.A::MyAMethod() is hard-coded i.e. the "magic" was already done by the C#->IL compiler. (*)
You could get the information you need to call the static method via reflection, e.g. (without error handling and rather crude)
public class C : A.B
{
public void MyCMethod()
{
Type parent = GetType().BaseType;
Type outer = parent.DeclaringType;
System.Reflection.MethodInfo mi = outer.GetMethod("MyAMethod");
mi.Invoke(null, null);
return;
}
}
but there is probably a better solution for your specific problem.
(*) and the c# compiler does that only as specified in http://msdn.microsoft.com/en-us/library/ms228593.aspx
3.7 Scopes
The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name [...]
- The scope of a member declared by a class-member-declaration (§10.1.6) is the class-body in which the declaration occurs. In addition, the scope of a class member extends to the class-body of those derived classes that are included in the accessibility domain (§3.5.2) of the member.class B is part of the class-body of class A, class C is not. And class C is also not derived from class A.
Simply do
public class C : A.B
{
public void MyCMethod()
{
A.MyAMethod();// I need to call this
}
}
As the method is static you can call it from anywhere through class A
You set MyAMethod to be static, so just call A.MyAMethod() inside your MyCMehtod()
Regards
A static method, field, property, or event is callable on a class even when no instance of the class has been created. And according to the data given in Staic Members Functions. You can call a static members directly with the Class name. So, in your case
A.MyAMethod(); will do the stuff.
You can't call MyAMethod() that way directly cause it doesn't belong to class B and you are inheriting class B; instead it's a static member of class A and Hence you have to qualify it before calling A.MyAMethod();
If you would have inherited class A instead then your code would do fine cause class C will inherit the method as well.
OR
Change your code to accomodate what you want like
public class A
{
public static void method()
{
Console.WriteLine("method in base class");
}
public class B
{
public void bmethod()
{
A.method();
}
}
}
public class C : A.B
{
public void cmethod()
{
bmethod();
}
}

Is it possible to add methods to classes with PostSharp? If yes, is it possible to then reference those methods from other classes?

Let's say I have a class Abc:
class Abc {
}
and that I'd like to externally add some method m() to it. I guess it's probably possible to do this, although I am not sure how. Assuming it is possible to do that, let's then say Abc does have, from now on, a m() method.
Now, imagine I have other class Def:
class Def {
public void x(Abc abc) {
abc.m();
}
}
Would this code run with PostSharp? To the more distracted reader, the problem with this is that in a standard C# class program, our compiler might not know the Abc class has a m() method.
My gut feeling is that this wouldn't work with PostSharp. Am I mistaken?
(Maybe you can use the DLR to accomplish if my PostSharp solutions aren't sufficient?)
Yes you can. You would use introducemember attribute in an instance scoped aspect. Your best bet is to implement an interface using postshsrp then reference your target class as that interface to expose the method. You can also use Post.Cast<>() to access it at design time.
Here are two methods to do this. The first is via an interface, the second is using stubs.
Method 1 - Interface
public class Program
{
static void Main(string[] args)
{
Customer c = new Customer();
var cc = Post.Cast<Customer, ISomething>(c);
cc.SomeMethod();
}
}
public interface ISomething
{
void SomeMethod();
}
[AddMethodAspect]
public class Customer
{
}
[Serializable]
[IntroduceInterface(typeof(ISomething))]
public class AddMethodAspect : InstanceLevelAspect, ISomething
{
#region ISomething Members
public void SomeMethod()
{
Console.WriteLine("Hello");
}
#endregion
}
Method 2 - stubs
public class Program
{
static void Main(string[] args)
{
Customer c = new Customer();
c.SomeMethod();
}
}
[AddMethodAspect]
public class Customer
{
public void SomeMethod() { }
}
[Serializable]
public class AddMethodAspect : InstanceLevelAspect
{
[IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
public void SomeMethod()
{
Console.WriteLine("Hello");
}
}
More Info
Just in case there are some issues with using the Cast<>() function, it doesn't do an actual cast. The compiled result looks like:
private static void Main(string[] args)
{
Customer c = new Customer();
ISomething cc = c;
cc.SomeMethod();
}
You can do it if the class is in a different assembly.
On the other hand, if the classes are in the same module, then you are right, the C# compiler won't compile it. Why not implement m() like this in C#, then replace the implementation with PostSharp?
class Abc
{
public void m()
{
throw new NotImplementedException ();
}
}
Edit:
What if you put m() in an interface, then use PostSharp to implement the interface on your class? Then you can call the method by casting to that interface.
interface IM
{
void m();
}
class Def {
public void x(Abc abc) {
if (abc is IM)
((IM) abc).m();
}
}

Categories