C# Delegate under the hood question - c#

I was doing some digging around into delegate variance after reading the following question in SO : Delegate.CreateDelegate() and generics: Error binding to target method
I found a very nice bit of code from Barry kelly at
https://www.blogger.com/comment.g?blogID=8184237816669520763&postID=2109708553230166434
Here it is (in a sugared-up form :-)
using System;
namespace ConsoleApplication4
{
internal class Base
{
}
internal class Derived : Base
{
}
internal delegate void baseClassDelegate(Base b);
internal delegate void derivedClassDelegate(Derived d);
internal class App
{
private static void Foo1(Base b)
{
Console.WriteLine("Foo 1");
}
private static void Foo2(Derived b)
{
Console.WriteLine("Foo 2");
}
private static T CastDelegate<T>(Delegate src)
where T : class
{
return (T) (object) Delegate.CreateDelegate(
typeof (T),
src.Target,
src.Method,
true); // throw on fail
}
private static void Main()
{
baseClassDelegate a = Foo1; // works fine
derivedClassDelegate b = Foo2; // works fine
b = a.Invoke; // the easy way to assign delegate using variance, adds layer of indirection though
b(new Derived());
b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection
b(new Derived());
}
}
}
I understand all of it except this one (what looks very simple) line.
b = a.Invoke; // the easy way to assign delegate using variance, adds layer of indirection though
Can anyone tell me:
how it is possible to call invoke without passing the param required by the static function.
When is going on under the hood when you assign the return value from calling invoke
What does Barry mean by extra indirection (in his comment)

He isn't calling Invoke (note the lack of ()), he's using implicit delegate creation to set b equal to a new derivedClassDelegate instance that points to the Invoke method of a. The additional indirection is that when b is invoked, it calls a.Invoke(new Derived()) rather than just a(new Derived()).
To make what's actually happening more explicit:
baseClassDelegate a = Foo1; // works fine
derivedClassDelegate b = Foo2; // works fine
b = new derivedClassDelegate(a.Invoke); // the easy way to assign delegate using variance, adds layer of indirection though
b(new Derived());
b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection
b(new Derived());
The first call to b results in a chain like this (parameters eliminated for simplicity):
b() -> a.Invoke() -> Foo1()
The second call to b results in this:
b() -> Foo1()
However
This is only needed if you need a delegate of one signature to invoke a delegate of another (less restrictive) signature. In his example, you could just set b = Foo1 and it would compile, but that wouldn't illustrate the point.

Related

Does the C# compiler treat a lambda expression as a public or private method?

Internally, the compiler should be translating lambda expressions to methods. In that case, would these methods be private or public (or something else) and is it possible to change that?
It depends. With the current version of Visual Studio, the methods that implement lambdas are never public, but they're not always private. A simple program to test some versions of lambdas:
public class Program
{
public static void Main()
{
var program = new Program();
Try("A", program.A);
Try("B", program.B);
Try("C", program.C);
Console.ReadKey();
}
private static void Try(string name, Func<Action> generator)
{
var mi = generator().Method;
Console.WriteLine($"{name}: DeclaringType={mi.DeclaringType}, Attributes={mi.Attributes}");
}
private Action A() => () => { };
private Action B() => () => { ToString(); };
private Action C()
{
var c = 1;
return () => c.ToString();
}
}
prints
A: DeclaringType=Scratch.Program+<>c, Attributes=PrivateScope, Assembly, HideBySig
B: DeclaringType=Scratch.Program, Attributes=PrivateScope, Private, HideBySig
C: DeclaringType=Scratch.Program+<>c__DisplayClass4_0, Attributes=PrivateScope, Assembly, HideBySig
A's lambda doesn't have any captures. It's created as an internal method of an empty closure class.
B's lambda captures this. It's created as a private method of the containing class.
C's lambda captures c. It's created as an internal method of a non-empty closure class.
All of this is undocumented and has changed in the past, so it would be good to avoid relying on it. What matters is that when you call the anonymous method, it behaves as specified. If you need anything more than that, you shouldn't be using anonymous methods. Depending on what you're after, you might either still be able to use lambdas, but with expression trees, or you might need to create regular named methods instead.
Internally, the compiler should be translating lambda expressions to methods.
I assume by "lambda" you mean a lambda converted to a delegate type. Lambdas converted to expression tree types are certainly not generated as methods.
The compiler does in fact turn such lambdas into methods, yes. There is no requirement that it does so, but doing so is convenient.
In that case, would these methods be private or public (or something else) and is it possible to change that?
The question is somewhat incoherent. Suppose I told you that a lambda was a public method. It has no name accessible from C#; how would you take advantage of its public-ness? Accessibility modifiers apply to members with names. The very notion of accessibility domain gives the domain of a name during name resolution.
In practice of course the compiler has to generate some accessibility bits for the metadata of the uncallable-by-you method. Methods generated on closure classes are internal, as that is the most convenient way to make usage of them verifiable. Methods generated without closures can be private.
Again, none of this is required, and all of it is implementation detail subject to change. You should not be attempting to take advantage of the code generation details of the compiler.
From the CLR via C# book by Jeffrey Richter
The compiler automatically defines a new private method in the class
... The compiler creates the name of the method for you automatically
... anonymous methods generated by the compiler always end up
being private, and the method is either static or nonstatic depending
on whether the method accesses any instance members
So the method is declared as private or internal.
For example the code
class AClass {
public void SomeMethod() {
Action lambda = () => Console.WriteLine("Hello World");
lambda();
}
}
will produce IL declaration as
.field private static class [mscorlib]System.Action 'CS$<>9__CachedAnonymousMethodDelegate1'
As you can see it is private static field.
However notice that lambda expression can be optimized, if you change example to
class AClass
{
string a = "Hello World";
public void SomeMethod()
{
Action lambda = () => Console.WriteLine(a);
lambda();
}
}
compiler will optimize it and there would be no lambda declaration at all
IL_0001: ldstr "Hello World"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
As #hvd mentioned there's a difference between a lambda expression uses parameters from its surrounding environment (closure case) or not. See: Why do some C# lambda expressions compile to static methods?
So the question only makes sense for the non-closure case when the lambda expression can be converted into a delegate wrapper without having any outside dependencies.
You can pass that generated class (which basically wraps a delegate) around and it will always refer to the generated delegate in the defining assembly. So you can invoke it from anywhere if the assembly is referenced.
Just verified that passing and executing an Action defined in another assembly works although the Action.Method itself is marked internal.
// Main, first assembly
namespace ConsoleApplication1
{
public class B : IB
{
Action _action;
public void AddAction(Action act)
{
_action = act;
}
public void Invoke()
{
Console.WriteLine(_action.Target);
Console.WriteLine("Is public: {0}", _action.Method.IsPublic);
_action();
}
}
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
a.AddActionTo(b);
b.Invoke();
Console.ReadKey();
}
}
}
In other assembly:
namespace OtherAssembly
{
public interface IB
{
void AddAction(Action act);
}
public class A
{
public void AddActionTo(IB b)
{
Action act = () => { };
b.AddAction(act);
}
}
}

Overriding and calling same method in Base class constructor in C#

My fret is: In the code presented below, it should display A then B. But it displays B then B. Why is it so?
What I feel is, constructor of A gets executed first when creating object of B. In that case, the method in B would not be hitted right? So it should be A.Display() and should result A. Also, then a.Display() should return B because we have override.
So I expect A then B. Because its not overloading but overriding. I know the definition of these things, I expect to understand the reason for this behavior and how it works internally as I am not convinced with BB but AB.
Code
class A
{
public A()
{
this.Display();
}
public virtual void Display()
{
Console.WriteLine("A");
}
}
class B :A
{
public override void Display()
{
Console.WriteLine("B");
}
}
class C
{
static void Main()
{
A a = new B();
a.Display();
Console.WriteLine();
Console.ReadLine();
}
}
Outputs
1) On override of Display method in the derived class yields the following:
A a = new A(); // ---> AA
B a = new B(); // ---> BB // I expect AB.
A a = new B(); // ---> BB // I expect AB.
2) using the NEW keyword in the Display method in derived class yields the following:
B a = new B(); // ---> AB // I Expect AA here.
A a = new B(); // ---> AA
A a = new A(); // ---> AA
3) More interesting findings are:
When I use base.Display() in the derived constructor with override of the base method in derived class, it gives me BAB
I do not see any logic at least in this. because, it should give BBB
What I feel is, constructor of A gets executed first when creating object of B.
Correct.
In that case, the method in B would not be hit right?
This is incorrect.
In similar code in C++ you would be correct. In C++ there is a rule that virtual function dispatch tables are built as the object is being constructed. That is, when the "A" constructor is entered, the vtable is filled in with the methods in "A". When control goes to the "B" ctor, the vtable is then filled in with the methods of B.
This is not the case in C#. In C# the vtable is filled in the moment the object comes out of the memory allocator, before either ctor is executed, and it does not change after that. The vtable slot for the method always contains the most derived method.
Therefore calling a virtual method in a ctor as you are doing here is a very bad idea. A virtual method can be called where the implementation is on a class whose ctor has not run yet! It might therefore depend on state that has not yet been initialized.
Note that field initializers run before all ctor bodies, so fortunately an override on a more derived class will always run after the field initializers of the overriding class.
The moral of the story is: simply don't do that. Don't ever call a virtual method in a ctor. In C++ you might get a different method than you expect, and in C# you might get a method that uses state that is not initialized. Avoid, avoid, avoid.
Why we shouldn't call virtual methods inside ctor? Is it because we get only the (latest derived) results only) always in the vtable?
Yes. Let me illustrate with an example:
class Bravo
{
public virtual void M()
{
Console.WriteLine("Bravo!");
}
public Bravo()
{
M(); // Dangerous!
}
}
class Delta : Bravo:
{
DateTime creation;
public override void M()
{
Console.WriteLine(creation);
}
public Delta()
{
creation = DateTime.Now;
}
}
OK, so the expected behavior of this program is that when M is called on any Delta, it will print out the time that the instance was created. But the order of events on new Delta() is:
Bravo ctor runs
Bravo ctor calls this.M
M is virtual and this is of runtime type Delta so Delta.M runs
Delta.M prints out the uninitialized field, which is set to the default time, not the current time.
M returns
Bravo ctor returns
Delta ctor sets the field
Now do you see what I mean when I say that the overriding method might rely on state that is not initialized yet? In any other usage of M, this would be fine because the Delta ctor would already be finished. But here M is called before the Delta ctor even starts!
You create an instance of an object B. It uses the code of the constructor that is defined on class A as you did not override it in B. But the instance is still B, so other methods called in the constructor are the ones defined in B, not A. Hence you see the result of Display() defined in class B.
Update based on update of the question
I'll try to explain the "weird" results you're getting.
When overriding:
B a = new B(); // ---> BB // I expect AB.
A a = new B(); // ---> BB // I expect AB.
This is covered above. When you override a method on a child class, this method is used if you're using an instance of the child class. This is a basic rule that the methods used are decided by the class of the instance of a variable, not by the class used to declare the variable.
When using new modifier for the method (hiding inherited method)
B a = new B(); // ---> AB // I Expect AA here.
Now there's two different behaviours here:
When the constructor is used, it's using the constructor in class A. As the inherited method is hidden in the child class, the constructor is using Display() method from class A and hence you see A printed.
When you later call Display() directly, the instance of the variable is B. For that reason, it uses the method defined on class B which prints B.
Initial statement
I'll start with the base code, I have adapted it to run in LINQPad (I did also change it to Write instead of WriteLine because I'll not preserve the new lines in the explanation anyway).
class A
{
public A()
{
this.Display();
}
public virtual void Display()
{
Console.Write("A"); //changed to Write
}
}
class B :A
{
public override void Display()
{
Console.Write("B"); //changed to Write
}
}
static void Main()
{
A a = new B();
a.Display();
}
The output is:
BB
In your initial question you said you were expecting:
AB
Whats happening here (as Szymon attempted to explain) is that you are creating an object of type B and the class B overrides the method Display of the class A. So whenever you call Display on that object it will be the method of the derived class (B), even from the constructor of A.
I will go over all the cases you mention. I want to encourage to read it carefully. Also, be open minded because this does not match what happens in certain other languages.
1) On override of Display method in the derived class
This is the case where you are overriding the method, ie:
public override void Display()
{
Console.Write("B"); //changed to Write
}
When you override, for all practical uses the method that will be used is the method of the derived class. Think of override as replace.
Case 1:
A a = new A(); // ---> AA
We are ok, with that.
Case 2:
B a = new B(); // ---> BB // I expect AB.
As mentioned above, calling Display on the object will always be the method on the derived class. So, both calls to Display yield B.
Case 3:
A a = new B(); // ---> BB // I expect AB.
This is a variant of the same confusion. The object is clearly of type B, even if you have it in a variable of type A. Remember that in C# the type is a property of the of the object not of the variable. So, the result is the same as above.
Note: You can still use base.Display() to access the method that was replaced.
2) Using the NEW keyword in the Display method in derived class
This is the case where you are hiding the method, ie:
public new void Display()
{
Console.Write("B"); //changed to Write
}
When you hide the method, it means that the original method is still available. You can think of it as a different method (that happens to have the same name and signature). That is: the derived class is not replacing overriding that method.
Because of that, when you do a (virtual) call to the object where at compile time it was decided it was going to use the method of the base class... the method of the derived class is not taken into consideration (in practice, it acts as it weren't a virtual call).
Think of it like this: if you call the method using a varible of the base class... the code is not aware that there exists a derived class that hides the method and that that particular call may be executed with one of those object. Instead, it will use the method of the base class, regardless.
Case 1:
B a = new B(); // ---> AB // I Expect AA here.
You see, at compile time the call in the constructor was set to use the method of the base class. That one gives A. But since the variable is of type B the compiler is aware that the method was hidden for the second call.
Case 2:
A a = new B(); // ---> AA
Here, neither in the constructor nor in the second call it will use the new method. It is not aware of it.
Case 3:
A a = new A(); // ---> AA
And I think this one is clear.
3) Using base.Display()
This the variant of the code where you do this:
public new void Display()
{
base.Display();
Console.Write("B"); //changed to Write
}
base.Display() is gonna be the method in the base class (A), no matter what.
Further reading
You said you want to learn how this works internally.
You can go deeper by reading Microsoft's C# Spec on Virtual Methods
Then read Eric Lippert's Implementing the virtual method pattern in C# (part 1, part 2 and part 3)
You may also be interested:
Anders on virtual calls from constructors.
Eric Lippert's Why Do Initializers Run In The Opposite Order As Constructors? (part 1 and part 2)
Others explanations of Virtual Methods from the web:
What's the difference between override and new? (msdn.com)
C# Virtual (dotnetpearls.com)
Understanding virtual, override and new keyword in C# (dotnet-tricks.com)
Understanding C#: Using virtual and override (oreilly.com)
You may be confusing yourself by naming the class a while instantiating it as class B. If you are looking to call the virtual method you could use the base keyword. The following code writes A B
class A
{
public A()
{
//this.Display();
}
public virtual void Display()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void Display()
{
base.Display();
Console.WriteLine("B");
}
}
class C
{
static void Main(string[] args)
{
A a = new B();
a.Display();
Console.WriteLine();
Console.ReadLine();
}
}
Also note you can see why your code is displaying B B by setting a breakpoint at the beginning and then walking through your code execution line-by-line (F11).
What I understood is , in case of virtual method, same method slot is shared among the parent and child object.
If so, then I think when an object virtual method is called , by somehow compiler updates the method slot with appropriate method address so that exact method is jitted and executed In c#.

Elegant solution to class design

I have following design problem programming application in C#.
I have classes A and B that both derives from C. I cannot change theirs definition because they are defined in external assembly and are not defined as partial too.
What I am trying to achieve is to differ functionality basing on weather provided C object is of type A or B. Of course I dont want to use if statements comparing runtime types of provided object. Is it possible with extensions methods? I dont think so.
Any solution? :)
It should be possible with extension methods by using generics.
Multiple approaches are possible, but this one is simplest. Although you do get that if
public static void Foo<T>(this T objectC)
where T: C
{
if(typeof(T)==typeof(B){ //or for runtime check: if(objectC is B)
//specific
}
}
you could then call Foo on any instance of A or B.
You mention you don´t want if statements, but I'm not sure to which extend you're trying to avoid that? The only way to completely avoid it, is to have 2 extension methods, one for A and one for B, (which in turn can call a common method for C), but I think you're trying to avoid multiple extension methods?
edit If you absolutely want to prevent if's, you'll have to use multiple extension methods as shown in Frederik's post. You could add an extension for the baseclass as well, that only gets called if the type is not known during compilation. But that would still need an if ;)
public static void Foo(this A a)
{
}
public static void Foo(this B b)
{
}
public static void Foo(this C c)
{
if(c is A)
Foo((A)c);
else if(c is B)
Foo((B)c);
else
throw new NotSupportedException(c.GetType().FullName);
}
If the type is always known at compile time, you can simply use the 2 extension methods for A en B.
You could try this:
public static class CExtensions {
public static void DoIt( this B foo ) {}
public static void DoIt( this A foo ) {}
}
But, I don't think that this will work:
C x = new A();
x.DoIt();
I don't think it will compile, but, I can't test it right now.
Purely from a feasibility point of view, it is possible using reflection and extension methods. Whether it makes sense in the context of your application, is something you should judge. Here goes the solution....
class C
{
}
class A : C
{
}
class B : C
{
}
static class Extender
{
public static void M(this B b)
{
Console.WriteLine(" Extension method on B");
}
public static void M(this A a)
{
Console.WriteLine(" Extension method on A");
}
}
static void Main(string[] args)
{
C c = new A();// The actual instance here will be created using some factory.
object instance = Activator.CreateInstance(c.GetType());
Type typeToFind = c.GetType();
Type typeToQuery = typeof(Extender);
var query = from method in typeToQuery.GetMethods(BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
where method.GetParameters()[0].ParameterType == typeToFind
select method;
// You would be invoking the method based on its name. This is just a quick demo.
foreach (MethodInfo m in query)
{
m.Invoke(instance, new object[] { instance });
}
}
To me this feels like a flaw in design.
If you can't have a common class to two sub classes which override and changes functionality without knowing the run time type you clearly have some issues with the overall design.
Should that functionality that differ depending on run time types really reside in those classes at all?
You could do it this way. Create a class with the different methods you need. In the same class define a delegate with the signature of this methods and keep a Dictionary where the keys are the types, and the values the delegates. Finally you can create an extension method for your class C that look into the dictionary using the type of the object that's executing the method itself and executes the right method. Something like this:
public static class CExtender
{
private static void DoItA(C anA)
{
MessageBox.Show("A");
}
private static void DoItB(C aB)
{
MessageBox.Show("B");
}
private static void DoItC(C aC)
{
MessageBox.Show("C");
}
delegate void DoItDel(C aC);
private static Dictionary<Type, DoItDel> _doItDels;
private static Dictionary<Type, DoItDel> DoItDels
{
get
{
if (_doItDels == null)
{
_doItDels = new Dictionary<Type, DoItDel>();
_doItDels[typeof(A)] = new DoItDel(DoItA);
_doItDels[typeof(B)] = new DoItDel(DoItB);
}
return _doItDels;
}
}
// the only public part is the extension method
public static void DoIt(this C aC)
{
DoItDel aDel;
if (DoItDels.TryGetValue(aC.GetType(), out aDel))
aDel(aC);
else
DoItC(aC);
}
}
You can use Decorater pattern in this case.
i.e. you can have 2 new classes of your own let say A1, B1 both deriving from C. (provided C is not a sealed class. If that's the case solution would be a bit different). Also A1 and B1 needs to wrap A and B corespondingly. You could inject instances of A and B through the constructors of A1 and B1.
You can also have a common interface which A1 and B1 both implmement. Interface needs to have the method which you need A1 and B1 to implement in their own ways. (A1 and B1 can delegate the calls to A or B as needed)
This way, in your client code, you can refer to A1 and B1 instances by their interface type and perform the common operation defined in the interface without knowing what their actual concrete implementations are.
Let me know if you need a code sample if I wasn't clear.
OK I found the answer.
The dynamic keyword is the clue here.
We can write:
void Handle(C c)
{
dynamic cc = c;
HandleSpecific(cc);
}
void HandleSpecific(A a)
{
//Specific behavior A
}
void HandleSpecific(B b)
{
//Specific behavior B
}
Drawbacks are of course - Risk of exception beacause of runtime binding introduced here and slight performance hit.

Polymorphic methods not working on C# 4

I just stumbled over a very interesting problem. Giving the following code:
using System;
class Program
{
class A { }
class B : A { }
private static void MyMethod(A a) /* first method */
{
Console.WriteLine("A"); ;
}
private static void MyMethod(B b) /* second method */
{
Console.WriteLine("B");
}
static void Main(string[] args)
{
var a = new A();
// Call first method
MyMethod(a);
A b = new B();
// Should call the second method
MyMethod(b);
Console.ReadLine();
}
}
I would expect that the second method will be called because the runtime type of the variable is B. Any ideas why the code calls the first method instead?
Thanks,
Tibi
Some clarifications: Polymorphism means several forms which has nothing to do where you declare the method.
Method overloading is a form of polymorphism, ad-hoc polymorphism.
The way polymorphism is normally implemented by using late binding.
dynamic is the workaround for this problem.
The fact is that this is not working in C#(or Java) it is a design decission which I would like to understand why was made, and none of the answers is answering this question.
/Tibi
This isn't an example of polymorphism at all. Polymorphism comes in to play when you call methods ON the object, not when the object is used as a parameter. This is just a simple example of method overloading.
You declared b as being of type A, so the compiler is going to link to the overload that uses type A. The linker doesn't care that B is a subclass of A, it just picks the overload with the closest signature to the declared types (not the actual types) of the parameters passed in.
if you want to force it to use the 2nd method, cast b in to type B in the method call.
MyMethod((B)b);
Method overloading in C#, by default, is determined statically at compile time. Since you are passing a statically typed variable of type A, it will statically bind to method with the A overload. Use the dynamic keyword to get the behavior you want.
static void Main(string[] args)
{
dynamic d = new A();
// Call first method
MyMethod(d);
d = new B();
// Call the second method
MyMethod(d);
Console.ReadLine();
}
It's not calling the second method because the reference to b itself is of type A. While b contains a reference to an instance of B, that is not an actual type of B, so the overload that uses an A reference is chosen.

How to invoke (non virtually) the original implementation of a virtual method?

I have the following situation:
In a 3rd party library (can not be modified):
class A { public virtual void M() {} }
class B : A { public override void M() {} }
In my own code:
class C : B { public override void M() {} }
From C's implementation of method M I want to call A's (but not B's!!). Can I?
Any tricks accepted, reflection included. I tried reflection already, but using the MethodInfo that I get from typeof(A) still generates a virtual call (calling C's implementation with subsequent stack overflow).
Deriving C from A is out of the question due to the complexity of reimplementing B.
you can generate dynamic method to make proxy that use Call (not CallVirt) instruction
var x = new C();
var m = typeof (A).GetMethod("M");
var dm = new DynamicMethod("proxy", typeof (void), new [] {typeof(C)}, typeof (C));
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, m);
il.Emit(OpCodes.Ret);
var action = (Action<C>)dm.CreateDelegate(typeof (Action<C>));
action(x);
Quite old question but I had a similar problem recently.
desco's answer gave the crucial hint.
But the generated proxy delegate should be encapsulated in class C, can be static and initialized via static constructor so time consuming reflection will be required only once.
// -- in foreign assembly
class A { public virtual void M() { Console.WriteLine("A.M"); }}
class B : A {public override void M() { Console.WriteLine("B.M"); }}
//
// -- in own assembly
class C : B
{
private static Action<C> call_A_M;
public override void M() {
call_A_M(this);
Console.WriteLine("C.M");
}
static C()
{
var m = typeof(A).GetMethod("M");
var dm = new DynamicMethod("", typeof(void), new[] { typeof(C) }, typeof(C));
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, m);
il.Emit(OpCodes.Ret);
call_A_M = (Action<C>)dm.CreateDelegate(typeof(Action<C>));
}
}
But as Dan Bryant already mentioned: never ever use such dirty tricks in production code.
In my previous answer I missed the fact that A and B are in an external library and cannot be modified. In that case, I would suggest a different approach. Basically, if the design flaw is in B, you can’t use B. Subclass from A instead.
The unfortunate consequence of this, of course, is that you may need to reimplement some or all of the functionality in B. You may be able to copy the code from Reflector if necessary. I realise that this sounds undesirable, but I still think it is preferable to using unmodifiable code that has a known issue that causes you problems.
I’m afraid this is not possible directly the way you describe — the purpose of virtual methods is for the overriding to be transparent. So the only way to do this at all is via a workaround.
Let me try to whip one up, but please be aware that this is a hacky suggestion. If you really need this construct in your code, it may be an indication that your code has a fundamental design flaw somewhere else, so restructuring something might be more desirable than filling it with yet another design flaw. But anyway, here goes...
class A {
public virtual void M() { m_protected(); }
protected void m_protected() { /* code goes here */ }
}
class B {
public override void M() { /* code here, possibly invoking base.M() */ }
}
class C {
public override void M() { m_protected(); }
}
You cannot do that. You should probably design your class hierarchy differently, because it looks strange that C inherits from B, while behaving like A.
Anyway, it could make sense in your case. Then you should make another method in A which you will not override:
class A {
protected virtual void basicM() {}
public virtual void M() { basicM(); }
}
class C {
public override void M() { basicM(); }
}
BTW, if you name the method as I did in the example, then you should probably rethink the whole thing. If this hierarchy is justified, than basicM probably performs something that deserves to be a separate method with a different name, perhaps even a public method.

Categories