Even though Iam in a derived class which should get me access to the derived protected members, I get the error
"Cannot access protected method 'BaseMethod' from here"
when trying to call other.BaseMethod();.
Can I get around this without having to make BaseMethod public? I also cannot make the method internal, since Base and Derived are in different assemblies.
class Base
{
protected void BaseMethod() { }
}
class Derived: Base
{
public void Doit(Base other)
{
other.BaseMethod();
}
}
You are using another class, as parameter, not the derived one.
in this case, the method should be public.
but have a look a this
How do you unit test private methods?
You can get around this by adding protected internal:
class Base
{
protected internal void BaseMethod() { }
}
class Derived : Base
{
public void Doit(Base other)
{
other.BaseMethod();
}
}
However, when inheritance is used then it can be called without any params. Let me show an example:
class Base
{
protected internal void BaseMethod() { }
}
class Derived : Base
{
public void Doit()
{
BaseMethod();
}
}
Related
Let's say I have a Screen class. This class has few abstract methods like EnterScreen, ExitScreen that are protected.
I want to change screen only through a ScreenManager class but I cannot since both methods are protected.
If I make methods public, I can make a call to both methods in ScreenManager but then I expose them to other classes that accept Screen class as a parameter thus they can easily call Enter and Exit Screen.
Any idea of how can make a call only through ScreenManager and without exposing both methods to other classes? (Only ScreenManager can change screens)
Thanks in advance.
EDIT: #derHugo provided an answer that I should use namespaces and internal keyword, however, I've already tried this but it's not working as expected (methods of the internal class are still accessible in the namespace that is not the same as the Screen class). I'll provide code below and behavior I'm getting.
namespace Test
{
public abstract class Screen<T>
{
internal abstract void EnterScreen();
internal abstract void ExitScreen();
}
}
// Seperate class
namespace Test
{
public class SimpleScreen : Screen<UnityEngine.GameObject>
{
internal override void EnterScreen() { }
internal override void ExitScreen() { }
}
}
// This DOESN'T HAVE A NAMESPACE but I can STILL access the internal methods of the Screen class.
public class GameManager : MonoBehaviour, IInitializable<SimpleScreen>
{
public void Initialize(SimpleScreen screen)
{
// I CAN REFERENCE .Enter & ExitScreen methods here
}
}
One way to approach it is to inject your screenManager instance into your Screen and pass it these Actions that it has privileged access to:
public abstract class Screen<T>
{
protected abstract Action GetEnterScreenAction();
protected abstract Action GetExitScreenAction();
public Screen(ScreenManagerInterface screenManager)
{
screenManager.SetScreenActions(GetEnterScreenAction(), GetExitScreenAction());
}
}
public class SimpleScreen : Screen<UnityEngine.GameObject>
{
private void EnterScreen() { }
private void ExitScreen() { }
protected override Action GetEnterScreenAction() { return EnterScreen;}
protected override Action GetExitScreenAction() { return ExitScreen;}
public SimpleScreen(ScreenManagerInterface screenManager, ....) : base(screenManager) { }
}
public interface ScreenManagerInterface
{
void SetScreenActions(Action enterScreenAction, Action exitScreenAction);
}
A need to make some public methods available only to some other classes may indicate a design flaw in classes relationship. Maybe moving part of the responsibilities into ScreenManager itself could solve this problem.
As you declare Screen class abstract you intent on public or protected methods that can be overridden. So the only option for you to hide them from other classes is to make them protected.
And the only way to access protected members is from the class itself, derived or nested type.
You can make the class ScreenManger nested inside your Screen and it will default to private or make it public. If I understood your question correctly I made an example but without Unity.
I hope it can help
public interface IInitializable<T>
{
}
public class SimpleScreen : Screen<object>
{
protected override void EnterScreen() { }
protected override void ExitScreen() { }
public class ScreenManager
{
private SimpleScreen _simpleScreen;
public void Awake()
{
_simpleScreen.EnterScreen();
}
}
}
public abstract class Screen<T>
{
protected abstract void EnterScreen();
protected abstract void ExitScreen();
}
public class GameManager : IInitializable<SimpleScreen>
{
public void Initialize(SimpleScreen screen)
{
var screenManager = new SimpleScreen.ScreenManager();
screenManager.Awake();
screen.
}
}
I have a base class and a class inheriting base. The base class has several virtual functions that the inherited class may override. However, the virtual functions in the base class has code that MUST to run before the inherited class overrides get called. Is there some way that I can call the base classes virtual functions first then the inherited class overrides. Without making a call to base.function().
I know I can simply make two functions, one that gets called, the other virtual. But is there a way I can keep the same names as well? I know I may need to change some things around.
class myBase
{
public virtual myFunction()
{ /* must-run code, Called first */ }
}
class myInherited : myBase
{
public override myFunction()
{ /* don't use base.myFunction();,
called from base.myFunction(); */ }
}
Similar question here.
C# doesn't have support for automatically enforcing this, but
you can enforce it by using the template method pattern. For example, imagine you had this code:
abstract class Animal
{
public virtual void Speak()
{
Console.WriteLine("I'm an animal.");
}
}
class Dog : Animal
{
public override void Speak()
{
base.Speak();
Console.WriteLine("I'm a dog.");
}
}
The trouble here is that any class inheriting from Animal needs to call base.Speak(); to ensure the base behavior is executed. You can automatically enforce this by taking the following (slightly different) approach:
abstract class Animal
{
public void Speak()
{
Console.WriteLine("I'm an animal.");
DoSpeak();
}
protected abstract void DoSpeak();
}
class Dog : Animal
{
protected override void DoSpeak()
{
Console.WriteLine("I'm a dog.");
}
}
In this case, clients still only see the polymorphic Speak method, but the Animal.Speak behavior is guaranteed to execute. The problem is that if you have further inheritance (e.g. class Dachshund : Dog), you have to create yet another abstract method if you want Dog.Speak to be guaranteed to execute.
A common solution that can be found in the .NET Framework is to split a method in a public method XXX and a protected, virtual method OnXXX that is called by the public method. For your example, it would look like this:
class MyBase
{
public void MyMethod()
{
// do something
OnMyMethod();
// do something
}
protected virtual void OnMyMethod()
{
}
}
and
class MyInherited : MyBase
{
protected override void OnMyMethod()
{
// do something
}
}
public abstract class BaseTemp
{
public void printBase() {
Console.WriteLine("base");
print();
}
public abstract void print();
}
public class TempA: BaseTemp
{
public override void print()
{
Console.WriteLine("TempA");
}
}
public class TempB: BaseTemp
{
public override void print()
{
Console.WriteLine("TempB");
}
}
There is no way to do what you're seeking other than the 2 ways you already named.
Either you make 2 functions in the base class, one that gets called and the other virtual.
Or you call base.functionName in the sub-class.
Not exactly. But I've done something similar using abstract methods.
Abstract methods must be overriden by derived classes. Abstract procs are virtual so you can be sure that when the base class calls them the derived class's version is called. Then have your base class's "Must Run Code" call the abstract proc after running. voila, your base class's code always runs first (make sure the base class proc is no longer virtual) followed by your derived class's code.
class myBase
{
public /* virtual */ myFunction() // remove virtual as we always want base class's function called here
{ /* must-run code, Called first */
// call derived object's code
myDerivedMustcallFunction();
}
public abstract myDerivedMustCallFunction() { /* abstract functions are blank */ }
}
class myInherited : myBase
{
public override myDerivedMustCallFunction()
{ /* code to be run in derived class here */ }
}
What do you think of this?
class myBase
{
public void myFunctionWrapper()
{
// do stuff that must happen first
// then call overridden function
this.myFunction();
}
public virtual void myFunction(){
// default implementation that can be overriden
}
}
class myInherited : myBase
{
public override void myFunction()
{
}
}
Don't get me wrong: I do not want to force an overriding method to call the base class like already asked 1000...times before :)
I wondered if there is any way to force the call of the base class implementation of a method inside the base class.
Example:
using System;
public class Program
{
public static void Main()
{
var c = new SubClass();
c.CallInfo();
}
internal class BaseClass {
protected virtual void Info(){
Console.WriteLine("BaseClass");
}
internal virtual void CallInfo() {
this.Info();
}
}
internal class SubClass : BaseClass {
protected override void Info() {
Console.WriteLine("SubClass");
}
internal override void CallInfo() {
base.CallInfo();
}
}
}
Output obviously would be SubClass. Is there any way to force the CallInfo method of BaseClass to call its own Info method so that the output would be BaseClass?
By marking your Info() method as virtual you are specifically asking for this type of inheritance behaviour to occur.
If you want to ensure that a method call in your base class is not overridden, you'll need to use a non-virtual method, e.g.
internal class BaseClass {
protected virtual void Info(){
this.FinalInfo();
}
protected void FinalInfo() {
Console.WriteLine("BaseClass");
}
internal virtual void CallInfo() {
this.FinalInfo();
}
}
No, you can't do that. The purpose of virtual methods is that derived classes can override the implementation and that the implementation is used even when called it from base classes.
If that causes problems then the method you want to run should not be a virtual method.
This would work, while it won't force an implementation by a subclass like virtual it'll allow you to override it.
public class Program
{
public static void Main()
{
var c = new SubClass();
c.CallInfo();
}
internal class BaseClass
{
protected void Info()
{
Console.WriteLine("BaseClass");
}
internal virtual void CallInfo()
{
this.Info();
}
}
internal class SubClass : BaseClass
{
protected new void Info()
{
Console.WriteLine("SubClass");
}
internal override void CallInfo()
{
base.CallInfo();
}
}
}
I have several classes which inherit from a BaseClass which has an abstract method called GetData. In one of them I want to basically inherit from again and provide use a new method called GetArticles which I call from GetData. Here's the code.
public abstract class BaseClass
{
internal abstract void GetData();
}
internal class FirstClass : BaseClass
{
internal override void GetData()
{
// calls GetArticles
}
protected void GetArticles()
{
}
}
internal class SecondClass : FirstClass
{
protected new void GetArticles()
{
}
}
GetArticles is never called in SecondClass. It calls the one in FirstClass, even though my object is of type SecondClass. I can't make GetArticles in FirstClass Abstract because I want to use FirstClass in its own right.
Any suggestions?
Your method has to marked as virtual in FirstClass and overriden using override keyword in SecondClass.
internal class FirstClass : BaseClass
{
internal override void GetData()
{
// calls GetArticles
}
protected virtual void GetArticles()
{
}
}
internal class SecondClass : FirstClass
{
protected override void GetArticles()
{
}
}
new modifier hides the underlying virtual method, which is not what you want. Check Knowing When to Use Override and New Keywords (C# Programming Guide) on MSDN.
Declare GetArticles in your FirstClass as virtual. In the second class remove new and add override
Make GetArticles virtual.
protected virtual void GetArticles()
{
}
Normal Class can not contain abstract method.Whereas abstract class can contain normal method.
If a normal class inherit abstract class and hold any abstract method than must be override due to inheritance in derived class.
Why does the protected method not appear?
If I make any public, internal or protected internal method they get appear.
class A
{
protected void AProtected() { }
}
class B:A
{
protected void BProtected() { }
}
class C:B
{
protected void CProtected() { }
}
class D:C
{
protected void DProtected() { }
}
class Program
{
static void Main(string[] args)
{
D classD = new D();
classD. //no method appear.
}
}
Because protected methods are accessible to the current class and subclasses of that class. Program is not a subclass of D.
Documentation
A protected member is accessible within its class and by derived class instances.
Accessibility levels
Since I notice confusion: you can call those protected methods from inside the subclass but you cannot call them from outside the subclass onto that subclass.
This might illustrate it:
Create two classes that don't have anything to do with eachother
MyMethod is NOT accessible
Add inheritance between these two classes
MyMethod IS accessible from the subclass
Try to call the method from another class
MyMethod is NOT accessible
Because that's the whole idea of protected. Protected members are only accessible by the declaring class and other classes that inherit from it.
You can find the official documentation here.
Because protected methods are not visible outside of the class or a class that inherits from that class.
From MSDN:
The protected keyword is a member access modifier.
A protected member is accessible within its class and by derived class instances.
You could call DProtected() within D, but not outside of D.
Protected is similar to private in that in can only be accessed from within the class, but has the added benefit of being accessible from inherited classes.
Your class Program (and its main method) are not able to access private or protected methods of your other classes, only public.
Protected methods can be called within derived classes only:
class A {
// This method can be called within derived classes only
protected void ProtectedA() {...}
// This method can be called within classes that are in the same namespace
internal void InternalA() {...}
// This method can be called either within derived classes only or
// within classes that are in the same namespace
protected internal void InternalOrProtectedA() {...}
}
class B: A {
protected void ProtectedB() {
// You can call A.ProtectedA() here since B is derived from A
}
}
class Program {
static void Main(string[] args)
// You can NOT call A.ProtectedA() here since B is NOT derived from A
// But you can call
// A.InternalA() since classes Program and A are in the same namespace
// A.InternalOrProtectedA() on the same reason
}
}
Another one to watch out for is if the method in the derived class is static. You can't call instance methods from a static method in a derived class, regardless of visibility/access modifiers.
If you have
namespace A
{
public class AClass
{
public void MethodCall()
{
xxx
}
}
}
Works
namespace B
{
public class BClass : A.AClass
{
public void Go()
{
A.AClass.MethodCall();
}
}
}
Doesn't Work
namespace B
{
public class BClass : A.AClass
{
public **static** void Go()
{
A.AClass.MethodCall();
}
}
}