This question already has answers here:
New keyword: why is the derived method not called?
(2 answers)
C# & generics - why is method in base class called instead of new method in derived class?
(4 answers)
Closed last month.
I'm trying to implement Curiously recurring template pattern(CRTP) in c#.
here is some code i wrote.
using System;
using System.Collections;
using System.Collections.Generic;
// Curiously recurring template pattern in c#
namespace MyApp
{
public class Program
{
public static void Main (string[] arg)
{
new Child().CallChildMethod();
}
}
public abstract class Base <T> where T: Base<T>, new ()
{
// Game loop
void Upate ()
{
Method ();
}
public void CallChildMethod ()
{
T t = (T)this;
t?.Method ();
}
public void Method ()
{
Console.WriteLine ("Base Method!");
}
}
public class Child: Base <Child>
{
public new void Method ()
{
Console.WriteLine ("Child Method!");
}
}
}
In output i'm getting
Base Method!
but my code should print
Child Method!
any idea?
Expected
I want to access child class object in base class instead of overriding base methods and please suggest is there any other way to do the same?.
Related
This question already has answers here:
Call method in class from another class in C#
(5 answers)
Closed 1 year ago.
I have a strange problem.
I created two classes AdvertisementHelper(namespace AdvertisementHelper) and Doof (namespace blabla), now I want to use the method bad_code from class Doof in class AdvertisementHelper.
AdvertisementHelper.cs:
using blabla;
namespace AdvertisementHelper
{
class AdvertisementHelper
{
Doof d = new Doof();
d.bad_code();
}
}
Doof.cs:
namespace blabla
{
class Doof
{
public void bad_code()
{
}
}
}
This is not my first C# program, I have done this many times and I never had such problems.
blabla and AdvertisementHelper are part of the same Visual Studio project.
d.bad_code and bad_code is not defined in this context
.NET Framework 4.7.2
You cannot have code (a method call, that is) floating around just anywhere in a class.
class AdvertisementHelper
{
Doof d = new Doof(); // <= OK, because interpreted as class field
d.bad_code(); // <= doesn't work!
}
You need to put it into a method, for example.
class AdvertisementHelper
{
Doof d = new Doof(); // <= OK, because interpreted as class field
public void Execute()
{
d.bad_code(); // <= Inside a method = OK!
}
}
This question already has an answer here:
How to make method call another one in classes?
(1 answer)
Closed 3 years ago.
I want to use a method from one file (class) in another one. You can see
// first class file
namespace AutomatskI
{
class Method{
public void client()
{
// some code
}
// second class file
namespace AutomatskaIA
{
class AutomaticTestRun
public void login()
{
// Here i want to use that code
client();
}
You should reference your first library in the second one
// Reference your first library like this
using AutomatskI;
namespace AutomatskaIA
{
class AutomaticTestRun
{
public void login()
{
// Then reach this class method like this
Method method = new Method();
method.client();
// Or use a static class instead by putting a 'static' tag in class name.
// So you don't have to create an instance of this class in order
// to use its methods. Then you can do it like this:
// Method.client();
}
// ...
And please format your code before posting so people would have an easier time reading your code.
This question already has answers here:
Counterpart to anonymous interface implementations in C#
(5 answers)
Closed 5 years ago.
I have a class that has an interface in it like so:
public class hcmTerminal {
... Code
public interface onDataReceived {
void isCompleted(bool done);
}
}
inside this class I I have the public property:
public onDataReceived mDataReceived;
then I have a function to set the delegate:
public void setDataReceived(onDataReceived dataReceived) { mDataReceived = dataReceived; }
Inside the hcmTerminal class I am am calling the delegate :
mDataReceived.isCompleted(true);
But I can't figure out the syntax to actually get when that delegate gets called, In java I can go:
myTerminal.setDataReceived(new hcmTerminal.onDataReceived(){
#Override
public void isCompleted(boolean done){
... Code
}
});
But if I try that in C# I get:
Cannot create an instance of the abstract or interface
'hcmTerminal.onDataReceived'
I haven't had to create a interface in C# before. this code is coming from how I implemented it in Java.
By using events you can accomplish that by
class HcmTerminal {
public event Action<bool> OnDataReceived;
public void Launch()
{
OnDataReceived?.Invoke(true /*or false*/);
}
}
You can then do:
var myTerminal = new HcmTerminal();
myTerminal.OnDataReceived += (isCompleted) => {};
Define a class implementing the interface:
class MyDataReceived : hcmTerminal.onDataReceived {
public void isCompleted(bool done) {
Console.WriteLine("call to isCompleted. done={0}", done);
}
}
Now you can call myTerminal.setDataReceived(new MyDataReceived())
However, this is a Java solution coded in C#, not a "native" C# solution. A better approach is to define a delegate in place of an interface:
public class HcmTerminal {
... Code
public delegate void OnDataReceived(bool done);
}
This would let you use multiple C# features for supplying delegate implementation, such as providing a method name, supplying an anonymous delegate, or using a lambda:
myTerminal.setDataReceived((done) => {
Console.WriteLine("call to isCompleted. done={0}", done);
});
Is it possible to add a method to a class from another project?
I have a class:
namespace ProjectLibrary
{
public class ClassA
{
// some methods
}
}
I want to add a method to save my object in a file, but I don't want to add this method in my project ProjectLibrary because I don't want to add reference to System.IO (I want to use this project for android application and PC application).
Is there a possibility to add a method SaveToFile() usable only in another project? Or create an abstract method in ClassA but define it in other project.
Like this :
using ProjectLibrary;
namespace ProjectOnPC
{
void methodExample()
{
ClassA obj = new ClassA();
// do something
obj.SaveToFile();// => available only in namespace ProjectOnPC
}
}
Thank you for help
You can use extension methods.
Example:
namespace ProjectOnPC
{
public static void SaveToFile(this Class myClass)
{
//Save to file.
}
}
The thing You are looking for is called Extension method:
DotNetPerls
MSDN link
What are Extension Methods?
Code for base class:
namespace ProjectLibrary
{
public ClassA
{
// some methods
}
}
Extension method:
using ProjectLibrary;
namespace ProjectOnPC
{
void SaveToFile(this ClassA Obj, string Path)
{
//Implementation of saving Obj to Path
}
}
Calling in Your program:
using ProjectLibrary;
using ProjectOnPc; //if You won't include this, You cannot use ext. method
public void Main(string[] args)
{
ClassA mObj = new ClassA();
mObj.SaveToFile("c:\\MyFile.xml");
}
You can create an extension method for this purpose.
Here's an example.
In your ProjectOnPc namespace create a class like this:
public static class ClassAExtension
{
public static void SaveToFile(this ClassA obj)
{
// write your saving logic here.
// obj will represent your current instance of ClassA on which you're invoking the method.
SaveObject(obj).
}
}
You can learn more about extension methods here:
https://msdn.microsoft.com/en-us//library/bb383977.aspx
I have the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
abstract class parent
{
public abstract void printFirstName();
protected virtual void printLastName()
{
Console.WriteLine("Watson");
}
protected void printMiddlename()
{
Console.WriteLine("Jane");
}
}
class child: parent
{
public override void printFirstName()
{
Console.WriteLine("Mary");
}
protected override void printLastName()
{
Console.WriteLine("Parker");
}
public void getMiddleName()
{
printMiddlename();
}
}
class Program: child
{
static void Main(string[] args)
{
child ch = new child();
ch.printFirstName();
ch.getMiddleName();
//ch.printLastName();
Console.Read();
}
}
}
This code runs properly and prints Mary Jane
However, when I uncomment ch.printLastName(); it showscompile error:
Why cant my Program Class call protected method of Child Class? especially when The child class has no problem calling the protected method (printMiddleName) of Parent class?
I guess you are confusing inheritance and access levels.
Your Program class inherits the printFirstName method from child. So inside your Program class you can access that method:
class Program : child
{
void Method() { this.printFirstName(); }
}
From outside a class you cannot access protected methods. But from inside a class you can access the protected methods of instance the same type:
class Program : child
{
void Method()
{
Program p1 = new Program();
p1.printFirstName(); // this works
child c1 = new child();
p1.printFirstName(); // this gives your compiler error
}
But you cannot access a protected method of an instance of a different type, even if it is a type you derived from.
See C# Reference for more details.
C# specification Section 1.6.2 Accessibility
Each member of a class has an associated accessibility, which controls
the regions of program text that are able to access the member
public - Access not limited
protected - Access limited to this class or classes derived from this class
Protected members are accessible only in current class (where it is defined) and classes derived from it.
In another word, you can access it only by this.
printLastName is protected. Check the MSDN page about access modifiers:
protected
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.
Protected keyword means that only a type and types that derive from that type can access the member.
so in this scenario you can't accesses Child.printLastName() from program Because it have two levels
Parent.printLastName() -> protected
Child.printLastName() -> protected
How inheritance work when you call Child.printLastName() from program class
it calls Parent.printLastName() -> Child.printLastName() But parent is not accessible that's the region it is showing compilation error.
Solution :-
You can make
Parent.printLastName() -> Internal access modifier
so Parent.printLastName() is accessible in this assembly .
namespace ConsoleApplication2
{
abstract class parent
{
public abstract void printFirstName();
internal virtual void printLastName()
{
Console.WriteLine("Watson");
}
public void printMiddlename()
{
Console.WriteLine("Jane");
}
}
class child : parent
{
public override void printFirstName()
{
Console.WriteLine("Mary");
}
protected override void printLastName()
{
Console.WriteLine("Parker");
}
public void getMiddleName()
{
printMiddlename();
}
}
class Program : child
{
static void Main(string[] args)
{
child ch = new child();
ch.printFirstName();
ch.getMiddleName();
ch.printLastName();
Console.Read();
}
}
}
Your code doesn't match your question - you're asking why can't Program class call protected method of it's parent (that is, child class in your example) - but your code is showing an instance of child class trying to publicly access a protected method - which fails, as intended.
This would work:
printLastName();
Or:
new Program().printLastName();
In layman's terms the method marked with protected is meaning that the class itself (child) can only access the method or other class inheriting from it.
Program calling the method off 'ch' can not access it, but an instance of Program (as its inheriting child) can call the method.