Here one more basic question asked in MS interview recently
class A {
public virtual void Method1(){}
public void Method2() {
Method1();
}
}
class B:A {
public override void Method1() { }
}
class main {
A obk = new B();
obk.Method2();
}
So which function gets called? Sorry for the typos.
B.Method1();
gets called because it properly overrides the virtual method A.Method1();
In this case B.Method1 gets called. This is because even though the variable is typed as A the actual type of the instance is B. The CLR polymorphically dispatches calls to Method1 based on the actual type of the instance, not the type of the variable.
Method1 from class B will be called, as you can see by running the below program:
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Method2();
Console.ReadLine();
}
}
class A
{
public virtual void Method1()
{
Console.WriteLine("Method1 in class A");
}
public void Method2()
{
Method1();
}
}
class B : A
{
public override void Method1()
{
Console.WriteLine("Method1 in class B");
}
}
The rule is "overriding member in the most derived class", which in this case would be "B".
B.Method1() is called due to the override.
B.Method1 is called because it is overridden in the class definition.
The question is a little ambigious...but...
obk.method2() is called. In turn, it calls obk.Method1, which, since it is an instance of B, has been overridden by B.Method1. So B.Method1 is what eventually gets called.
As everybody else has said, B.Method2 gets called. Here is a few other pieces of information so you understand what's going on:
((A)B).Method2();
B.Method2();
These will both call B.Method1() because it was properly overridden. In order to call A's Method1, there must be a base.Method1() call made from B (which is often but not always done in B.Method1's implementation).
If, however, B was defined in this way:
class B:A {
new public void Method1() { }
... then A's Method1() would be called because Method1 was not actually overridden, it was hidden and tucked away outside the rules of polymorphism. In general, this is typically a bad thing to do. Not always, but make sure you know very well what you're doing and why you're doing it if you ever do something like this.
On the flip side, using new in this way makes for some interesting interview questions as well.
Related
I want a particular method in one class to only be accessible by a particular class. For example:
public class A
{
public void LimitedAccess() {}
public void FullAccess() {}
}
public class B
{
public void Func()
{
A a = new A();
a.LimitedAccess(); // want to be able to call this only from class B
}
}
public class C
{
public void Func()
{
A a = new A();
a.FullAccess(); // want to be able to call this method
a.LimitedAccess(); // but want this to fail compile
}
}
Is there is a keyword or attribute that I can use to enforce this?
UPDATE:
Due to existing system complexity and time constraints, I needed a low impact solution. And I wanted something to indicate at compile time that LimitedAccess() could not be used. I trust Jon Skeet's answer that exactly what I had asked for could not be done in C#.
The question and Jon's answer are good for those who may run across this later. And the fact that this design smells can hopefully veer anyone away for choosing something like this as a desired a solution.
As mentioned in a comment, the C# friend conversation is useful reading if you are trying to solve a similar situation.
As for my particular solution: "why would A contain B's logic" (asked by #sysexpand in comments). That's the rub. B.Func() was called throughout the system I'm working on, but it primarily operated on a singleton of A. So what I ended up doing was moving B's Func() into A and making A.LimitedAccess() private. There were a few other details to work around, as there always are, but I got a low impact solution that gave me compile-time errors on callers to A.LimitedAccess().
Thanks for the discussion.
No. The only thing you could do would be to make LimitedAccess a private method, and nest class B within class A.
(I'm assuming you want all the classes in the same assembly. Otherwise you could put A and B in the same assembly, and C in a different assembly, and make LimitedAccess an internal method.)
Yes. What you are asking for is perfectly possible.
You can restrict access to methods and variables for a specific instance, by using an interface.
However, an interface alone cannot prevent someone from creating their own instance of the class, at which point they will have full access to that instance.
To do that, next you should nest it as a private class inside of another class in order to restrict access to the constructor.
Now you have a particular method in one class to only be accessible by a particular class.
In this example, only class B is ever able to access function LimitedAccess.
public interface IA
{
void FullAccess();
}
public class B
{
private class A : IA
{
public void LimitedAccess() {} //does not implement any interface
public void FullAccess() {} //implements interface
}
private A a = new A();
public IA GetA()
{
return (IA)a;
}
public void Func()
{
/* will be able to call LimitedAccess only from class B,
as long as everybody else only has a reference to the interface (IA). */
a.LimitedAccess();
}
}
//This represents all other classes
public class C
{
public void Func(IA ia)
{
ia.FullAccess(); // will be able to call this method
ia.LimitedAccess(); // this will fail to compile
}
}
public static class MainClass
{
public static void Main(string[] args)
{
B b = new B();
b.Func();
IA ia = b.GetA();
C c = new C();
c.Func(ia);
}
}
In case you just want to remind yourself (or team mates) to not call LimitedAccess everywhere, you could consider using explicit interface implementation or mark LimitedAccess as obsolete.
public interface IA
{
void LimitedAccess();
void FullAccess();
}
public class A : IA
{
private void LimitedAccess() { }
public void FullAccess() { }
void IA.LimitedAccess() => LimitedAccess();
void IA.FullAccess() => FullAccess();
}
public class B
{
public void Func()
{
IA a = new A();
a.LimitedAccess(); // want to be able to call this only from class B
}
}
public class C
{
public void Func()
{
A a = new A();
a.FullAccess(); // want to be able to call this method
a.LimitedAccess(); // -> fails to compile
}
}
Maybe this is a workaround.
Use the System.Runtime.CompilerServices and then you can either check the Name of the calling function and/or the file, in which the calling function is defined. If you have a class per file, the filename might be a substitude for the class name. Check it and block the call.
internal void MySecretFunction (string something,
[CallerMemberName] string memberName = null,
[CallerFilePath] string filePath = null,
[CallerLineNumber] int lineNumber = 0) {
if (!filePath.EndsWith(#"\goodClass.cs")) return;
// else do something
}
You could always see the calling type with a StackTrace.
Just note that when building in release mode, the call on the stack will get optimized, and its possible that the stack trace could return a completely different class, so just make sure to test it before you publish.
/// <summary>
/// Warning: Any class that calls this other than "B" will throw an exception.
/// </summary>
public void LimitedAccess()
{
if (new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType != typeof(B)) throw new Exception("Invalid Caller Type, B is only class able to call this method.");
}
Unfortunately you wont be able to know if its an error on compile time. Best you can do is throw an exception if it gets called, and add a comment warning people about it.
It is against OOP best practices to make such a design. Methods of classes are not supposed to be protected from being called.
If your design requires control over calling a method, then control should be exercised by testing the arguments - caller which is authorized to make a call would "know" the magic word to pass as the argument.
This is a variation of the solution suggested by #cowlinator using class AWithUnlimitedAccess derived from class A rather than class A implementing interface IA.
The result and the limitations are the same, but I like it better because (1) the limited access methods are defined inside its own class and (2) it's easier to add documentation comments.
public class A
{
public void FullAccess() { }
}
public class AWithUnlimitedAccess : A
{
public void LimitedAccess() { }
}
public class B
{
private AWithUnlimitedAccess a = new AWithUnlimitedAccess();
public A GetA()
{
return a;
}
public void Func()
{
a.FullAccess();
a.LimitedAccess();
}
}
// This represents all other classes
public class C
{
public A A;
public void Func()
{
A.FullAccess();
A.LimitedAccess(); // this will fail compile
}
}
public static class MainClass
{
static void Main(string[] args)
{
B b = new B();
b.Func();
C c = new C();
c.A = b.GetA();
c.Func();
}
}
Today I came up with an interesting problem. I noticed that the following code:
class A
{
public A()
{
Print();
}
public virtual void Print()
{
Console.WriteLine("Print in A");
}
}
class B : A
{
public B()
{
Print();
}
public override void Print()
{
Console.WriteLine("Print in B");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
}
}
Prints
Print in B
Print in B
I want to know why does it print the "Print in B" twice.
I want to know why does it print the "Print in B" twice.
You're calling a virtual method twice, on the same object. The object is an instance of B even during A's constructor, and so the overridden method will be called. (I believe that in C++, the object only "becomes" an instance of the subclass after the base class constructor has executed, as far as polymorphism is concerned.)
Note that this means that overridden methods called from a constructor will be executed before the derived class's constructor body has had a chance to execute. This is dangerous. You should almost never call abstract or virtual methods from a constructor, for precisely this reason.
EDIT: Note that when you don't provide another constructor call to "chain" to using either : this(...) or : base(...) in the constructor declaration, it's equivalent to using : base(). So B's constructor is equivalent to:
public B() : base()
{
Print();
}
For more on constructor chaining, see my article on the topic.
Unlike C++ where calls of virtuals in the constructor are restricted to the definition within the class itself, the overrides are fully honored in C#'s constructors. The practice is frowned upon, and for a good reason (link), but it is still allowed: A's constructor calls the override supplied by B, producing the output that you see. This is the normal behavior of overriden virtual functions.
Because B override's the Print method. Your variable a is of type B, and B's Print method looks like this:
public override void Print()
{
Console.WriteLine("Print in B");
}
If you do not call a base class constructor, the default constructor for the base class will be called implicitly (MSDN).
You would not get the double output if you defined your class A constructors this way:
class A
{
public A()
{
// does nothing
}
public A(object a)
{
Print();
}
}
The reason it prints "Print in B" both times is that Print() is overridden in the class B so B.Print() is what is called by both constructors.
I think you can force the A.Print() to be called in the A constructor as follows:
class A
{
public A()
{
((A)this).Print();
}
}
Hope this helps.
Because you have an instance of B which overrides Print, so that overridden method gets called. Also, A's ctor will run, followed by B's which is why it gets printed twice.
In looking at this question, commenter #Jon Egerton mentioned that MyClass was a keyword in VB.Net. Having never used it, I went and found the documentation on it:
The MyClass keyword behaves like an object variable referring to the current instance of a class as originally implemented. MyClass is similar to Me, but all method calls on it are treated as if the method were NotOverridable.
I can see how that could kind of be useful, in some specific scenarios. What I can't think of is, how would you obtain the same behaviour in C# - that is, to ensure that a call to a virtual method myMethod is actually invoked against myMethod in the current class, and not a derived myMethod (a.k.a in the IL, invoking call rather than callvirt)?
I might just be having a complete mental blank moment though.
According to Jon Skeet, there is no such equivalent:
No, C# doesn't have an equivalent of VB.NET's MyClass keyword. If you want to guarantee not to call an overridden version of a method, you need to make it non-virtual in the first place.
An obvious workaround would be this:
public virtual void MyMethod()
{
MyLocalMethod();
}
private void MyLocalMethod()
{
...
}
Then you could call MyLocalMethod() when a VB user would write MyClass.MyMethod().
There is no C# equivalent of the MyClass keyword in VB.Net. To guarantee that an overridden version of a method will not be called, simply make it non-virtual.
In addition to answers saying it doesn't exist, so you have to make it non-virtual.
Here's a smelly (read: don't do this!) work-around. But seriously, re-think your design.
Basically move any method that must have the base one called into 'super'-base class, which sits above your existing base class. In your existing class call base.Method() to always call the non-overridden one.
void Main()
{
DerivedClass Instance = new DerivedClass();
Instance.MethodCaller();
}
class InternalBaseClass
{
public InternalBaseClass()
{
}
public virtual void Method()
{
Console.WriteLine("BASE METHOD");
}
}
class BaseClass : InternalBaseClass
{
public BaseClass()
{
}
public void MethodCaller()
{
base.Method();
}
}
class DerivedClass : BaseClass
{
public DerivedClass()
{
}
public override void Method()
{
Console.WriteLine("DERIVED METHOD");
}
}
Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..
--edit--
I am mainly curious about overriding methods.
There isn't and shouldn't be anything to do that.
The closest thing I can think of off hand if something like having this in the base class:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
And allow the inheriting class override BeforeFoo and/or AfterFoo
Not in Java. It might be possible in C#, but someone else will have to speak to that.
If I understand correctly you want this:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
What you can do in Java to enforce usage of the superclass foo is something like:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.
Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.
EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.
The following example throws an InvalidOperationException when the base functionality is not inherited when overriding a method.
This might be useful for scenarios where the method is invoked by some internal API.
i.e. where Foo() is not designed to be invoked directly:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
Works:
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
Yells:
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
I use the following technique. Notice that the Hello() method is protected, so it can't be called from outside...
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
Example usage:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
Which produces:
You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super
If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.
No. It is not possible. If you have to have a function that does some pre or post action do something like this:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.
Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.
Don't think there's any feasible solution built-in. I'm sure there's separate code analysis tools that can do that, though.
EDIT Misread construct as constructor. Leaving up as CW since it fits a very limited subset of the problem.
In C# you can force this behavior by defining a single constructor having at least one parameter in the base type. This removes the default constructor and forces derived types to explcitly call the specified base or they get a compilation error.
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
In java, the compiler can only enforce this in the case of Constructors.
A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.
This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.
The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...
There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.
However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.
The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.
Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.
I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.
On the Android platform there is a Java annotation called 'CallSuper' that enforces the calling of the base method at compile time (although this check is quite basic). Probably the same type of mechanism can be easily implemented in Java in the same exact way. https://developer.android.com/reference/androidx/annotation/CallSuper
Why the following program prints
B
B
(as it should)
public class A
{
public void Print()
{
Console.WriteLine("A");
}
}
public class B : A
{
public new void Print()
{
Console.WriteLine("B");
}
public void Print2()
{
Print();
}
}
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Print();
b.Print2();
}
}
but if we remove keyword 'public' in class B like so:
new void Print()
{
Console.WriteLine("B");
}
it starts printing
A
B
?
When you remove the public access modifier, you remove any ability to call B's new Print() method from the Main function because it now defaults to private. It's no longer accessible to Main.
The only remaining option is to fall back to the method inherited from A, as that is the only accessible implementation. If you were to call Print() from within another B method you would get the B implementation, because members of B would see the private implementation.
You're making the Print method private, so the only available Print method is the inherited one.
Externally, the new B.Print()-method isn't visible anymore, so A.Print() is called.
Within the class, though, the new B.Print-method is still visible, so that's the one that is called by methods in the same class.
when you remove the keyword public from class b, the new print method is no longer available outside the class, and so when you do b.print from your main program, it actually makes a call to the public method available in A (because b inherits a and a still has Print as public)
Without the public keyword then the method is private, therefore cannot be called by Main().
However the Print2() method can call it as it can see other methods of its own class, even if private.