Method usage between two classes - c#

here is my code. I want to increase speed value with a.Quest() method. This method is in the first class. And the second class inherits from first class.
Increasing method is in second class but I use it in first class. That's what I'm trying to do. I don't want to write so much code in main.
However when I run the program, both a.Speed and b.Speed is equal to zero. I expect one of them to be 10. How can I fix that?
interface IElektroBeyin
{
int Speed{ get; set; } // Hız kontrolü
}
class AA : IElektroBeyin
{
public int Speed { get; set; }
public virtual void GetFaster() { }
public virtual void GetSlower() { }
public void Quest()
{
int x;
Console.WriteLine("Want to get faster ? 1- Yes");
x = Console.Read();
if (x == 1)
{
GetFaster();
}
}
}
class BB : AA
{
public override void GetFaster()
{
Speed += 10;
}
public override void GetSlower()
{
Speed -= 10;
}
}
static void Main(string[] args)
{
BB b = new BB();
AA a = new AA();
a.Quest();
Console.WriteLine(b.Speed);
Console.WriteLine(a.Speed);
Console.ReadLine();
}
}
}

AA a = new AA();
a.Quest();
AA.Quest() calls AA.GetFaster(), but this method is empty. That's why nothing happens when it is called. BB.GetFaster() is not called since it is in a derived class of AA. You probably want it to be the other way around.
Further, to get a number that a user enters, you can't use the return value of Console.Read(). Use int.Parse(Console.ReadLine()) or something similar.

Related

Why do the properties in my code not work?

I have created an interface and then derived a class from it:
public interface Ishape
{
void draw();
int Number { get; set; }
}
class Circle : Ishape
{
public Circle(int a)
{
number = a;
}
public void draw()
{
Console.WriteLine("Circle.");
}
private int number;
public int Number
{
get
{
return number;
}
set
{
if (value < -5)
number = -5;
}
}
public int GetNumber()
{
return number;
}
}
class Program
{
static void Main(string[] args)
{
Circle a1 = new Circle(-6);
Console.WriteLine(a1.GetNumber());
Console.ReadLine();
}
}
As you can see, there is an autoproperty in the interface. I then decided to create a property in the new class that derived from the interface that would set the variable "number" to -5 if the value is less than -5. For some reason, the property does not seem to be working. Using the constructor, I set the value of the variable to -6, and the property did not change the value to -5. Why?
This is because you are setting number = a and not Number = a in your constructor. Try this:
public Circle(int a)
{
Number = a;
}
Your Number Property is never actually set.
In your Circle constructor, change number to Number.
public Circle(int a)
{
Number = a;
}
Also, if you intend to use GetNumber as your publicly available get (and nothing more), then I would advise that you change the access modifier for your Number property in your Circle class.

How to use a function that declared in first class, use it in second class?

class Kontak : IElektroBeyin
{
int x = Console.Read();
switch(x){
case 1:
//Here I want to use GetSpeed function.
break;
}
}
class Pedal : Kontak
{
public void GetSpeed()
{
Speed += 10;
}
}
Hi, I want to use a function that declared in second class. I want to use it in first class. Is that possible ? Can I use GetSpeed function in class named Kontak ? Because I don't want to write a lot of codes in main.
I tried to create an example of Pedal in Kontak class.--- Pedal p = new Pedal();--- In case1 : --- p.GetSpeed();--- Finally I controlled my Pedal's and Kontak's Speed value. But they were both equal to zero.
You can declare it like this:
class Kontak
{
public virtual void GetSpeed(){}
public void SomeMethod()
{
// if overridden, it will call that method
// otherwise it will call this class's method
GetSpeed();
}
}
Then override it:
class Pedal : Kontak
{
public override void GetSpeed()
{
Speed += 10;
}
}

How to subscribe to an event with certain arguments c#?

I have an enumeration prior.
Each of my scripts has a property priority of prior type. (Every script has its own class)
I have a data provider, which can send events every frame.
I want a script to subscribe only to an event which has arguments with priority equal to the script's one.
For example, a script with moderate priority should receive only events with moderate parameter of event arguments
prior has too many members to create a special event argument class for each.
Unfortunately:
a)I know only how to subscribe to a certain event type.
b)I can't make a generic class for event arguments, because elements of enum are not types
How can I do it?
The project currently looks this way:
public class TDefault:MonoBehaviour,IDefault
{
public enum prior
{
none,
...,
terminal
};
prior priority;
public virtual void apply()//For override by scripts
{
}
void Start()
{
//There should be adding a method which calls apply() when event_manager
//sends Event with a certain priority
}
public TDefault ()
{
if(essential==null)
essential=new TEssential();
}
}
public class TApplyEventParam : EventArgs
{
public TDefault.prior priority;
public TApplyEventParam(TDefault.prior _priority)
{
priority=_priority;
}
}
public class event_manager : TDefault
{
//This has fixed type
event EventHandler<TApplyEventParam> handler=new EventHandler<TApplyEventParam>();
void Update ()
{
foreach (prior p in (prior[]) Enum.GetValues(typeof(prior)))
{
handler(this,new TApplyEventParam(p));
}
}
}
The problem you're dealing with, if I understood it correctly, is that you would like to have your event subscription conditionally called depending on the event payload (the priority value inside the TApplyEventParam). That is something that you cannot do which results in you having to filter out the unwanted events inside your event handler like proposed by #Henk-Holterman
Another approach could be to skip the usage of events and maintain your own list of subscribers inside the data provider.
Based on the terminology used by you in your question (not the code example) you could do something like this:
using System;
using System.Collections.Generic;
namespace Example
{
public enum Prior
{
None,
Moderate,
Terminal
};
public abstract class ScriptBase
{
public abstract Prior Prior { get; }
public abstract void Apply();
public void Start(DataProvider dataProvider)
{
dataProvider.Subscribe(Prior, Apply);
}
public void Stop(DataProvider dataProvider)
{
dataProvider.Unsubscribe(Prior, Apply);
}
}
public class ScriptHandlingModerateEvents : ScriptBase
{
public override Prior Prior
{
get { return Example.Prior.Moderate; }
}
public override void Apply()
{
Console.WriteLine("Handling moderate event by " + GetType().Name);
}
}
public class ScriptHandlingTerminalEvents : ScriptBase
{
public override Prior Prior
{
get { return Example.Prior.Terminal; }
}
public override void Apply()
{
Console.WriteLine("Handling terminal event by " + GetType().Name);
}
}
public class DataProvider
{
private readonly Dictionary<Prior, List<Action>> _subscribersByPrior;
public DataProvider()
{
_subscribersByPrior = new Dictionary<Prior, List<Action>>();
foreach (Prior prior in (Prior[])Enum.GetValues(typeof(Prior)))
{
_subscribersByPrior.Add(prior, new List<Action>());
}
}
public void Subscribe(Prior prior, Action action)
{
_subscribersByPrior[prior].Add(action);
}
public void Unsubscribe(Prior prior, Action action)
{
_subscribersByPrior[prior].Remove(action);
}
public void DoSomethingThatTriggersPriorEvents(int someValue)
{
Prior prior = someValue % 2 == 0 ? Prior.Moderate : Prior.Terminal;
foreach (var subscriber in _subscribersByPrior[prior])
{
subscriber();
}
}
}
public static class Program
{
public static void Main()
{
DataProvider dataProvider = new DataProvider();
var scriptHandlingModerateEvents = new ScriptHandlingModerateEvents();
scriptHandlingModerateEvents.Start(dataProvider);
var scriptHandlingTerminalEvents = new ScriptHandlingTerminalEvents();
scriptHandlingTerminalEvents.Start(dataProvider);
for (int i = 0; i < 10; i++)
{
dataProvider.DoSomethingThatTriggersPriorEvents(i);
}
scriptHandlingTerminalEvents.Stop(dataProvider);
scriptHandlingModerateEvents.Stop(dataProvider);
Console.WriteLine();
}
}
}
this way the DataProvider is not aware of scripts, but if that is not an issue, you could maintain a list of ScriptBase instances and check the Prior property inside the
DoSomethingThatTriggersPriorEvents like this:
public class DataProvider2
{
private readonly List<ScriptBase> _scripts = new List<ScriptBase>();
public void Subscribe(ScriptBase script)
{
_scripts.Add(script);
}
public void Unsubscribe(ScriptBase script)
{
_scripts.Remove(script);
}
public void DoSomethingThatTriggersPriorEvents(int someValue)
{
Prior prior = someValue % 2 == 0 ? Prior.Moderate : Prior.Terminal;
foreach (var script in _scripts)
{
if (script.Prior == prior)
{
script.Apply();
}
}
}
}

A field is fixed value for each class,field is not dependent instances ...?

In below example, i defined number field. This field will work as i wanted but it is not enough efficient to provide my expectations.
number value is fixed value for each class,number is not dependent instances and number support polymorphism. How can i do that ? Or is there another solution for not use unneccesary number field for instances ?
abstract class Main
{
public int number;
public virtual void dostuff(){
int x = number;
}
}
class Derived:Main
{
public ovverride void dostuff(){
int x = number;
}
}
You could just make the number a property and initialise is in each class constructor:
abstract class Main
{
public int number{get; private set;}
public void dostuff(){
int x = number;
}
}
class Derived:Main
{
public Derived()
{
number = 5; // Specific value for each derived class
}
public void dostuff(){
int x = number;
}
}
Looks like I got the wrong end of the stick -- you want to be able to set it statically per class type, which has already been answered.
You could make the property static and then add it to each class:
abstract class Main
{
public static int number;
public virtual void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public overide void dostuff(){
int x = Derived.number;
}
}
Edit: I am a bit confused by your comments about polymorhism so i have added some more examples.
Main obj = new Derived();
obj.doStuff(); //This will use Derived.number; as doStuff is and overidden virtual method.
However if you do the following:
abstract class Main
{
public static int number;
public void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public new void dostuff(){
int x = Derived.number;
}
}
Then you get different behaviour as below:
Main obj = new Derived();
obj.doStuff() // Will use Main.number
Derived obj2 = (Derived)obj;
obj2.doStuff() // Will use Derived.number
If you want some other kind of behaviour i havn't defined here please exaplin because i do not understand what you want.

Passing data to overridden base method in C#

Bit of a dumb question, but I'm wondering what the accepted way of passing data from back to an overridden base method is in c#.
e.g. I guess I could do:
class A
{
int x;
public virtual void DoStuff() {
Console.WriteLine(x);
}
}
class B : A
{
public override void DoStuff() {
x = 1;
base.DoStuff();
}
}
But is there a better method that for example doesn't require the use of a member variable?
One solution can involve the use of a protected method that has an argument to reuse code from the base class.
class A
{
public virtual void DoStuff() {
DoStuffInternal(0);
}
protected void DoStuffInternal(int x) {
Console.WriteLine(x);
}
}
class B : A
{
public override void DoStuff() {
DoStuffInternal(1);
}
}
Why not use a parameter?
class A
{
public virtual void DoStuff(int x) {
Console.WriteLine(x);
}
}
class B : A
{
public override void DoStuff(int x) {
//do stuff
int y = 1
base.DoStuff(y);
}
}
How about
abstract class A
{
protected abstract int X { get; }
public void DoStuff() {
Console.WriteLine(X);
}
}
class B : A
{
protected override int X { get { return 1; } }
}
You may use something like Template Method design pattern:
class A
{
public void DoStuff() {
var x = DoGetX();
Console.WriteLine(x);
}
protected abstract int DoGetX();
}
class B : A
{
protected override int DoGetX() {
return 1;
}
}
For almost every developer property is looks like simple wrapper around field, and we know that there are no such thing like virtual fields. So I think that abstract method is much more preferable solution in this case(we already discussed differences between properties and methods here).

Categories