so I have a problem:
When I'm trying to hand over a parameter from the Child-Class to the Base-Class, the parameter is not in the Base-Class:
public class Zeiteinheit : Shutdown_Time
{
public int Public_minuten
{
get { return _minuten; }
set { _minuten = value; }
}
public void Minuten_Zu_Sekunden_Umrechnung()
{
_sekunden = (_minuten * 60);
}
}
public class Shutdown_Time
{
protected int _sekunden;
protected string herunterfahrenTimer;
public string Public_herunterfahrenTimer
{
get { return herunterfahrenTimer; }
set { herunterfahrenTimer = $"-s -t {_sekunden}"; }
}
}
MainClass:
//Umrechnung der eingetragenen Zeit findet statt
obj_zeiteinheit.Minuten_Zu_Sekunden_Umrechnung();
//Herunterfahren mit der Umgerechneten Zeit von stunden in sekunden
System.Diagnostics.Process.Start("Shutdown", obj_shutdown_Time.Public_herunterfahrenTimer);
break;
Result of an debug
My Question is here, did i missunderstood something by the concept of inheriting or what is my mistake?
(Sorry for my very bad english, and thanks for the help!)
You seem to be asking "when I set a property or field in a base class, how do I trigger the updating of a property or field in a derived class?"
But then you showed code that outlines you want to set ZeitenHeit.Public_Minuten = 60, which does set _sekunden = 3600 but you then also want to update, in the same class, herunterfahrenTimer so it is -s -t 3600 because right now it isn't updated (the screenshot is null)
There is a small but critical difference between what you asked and what you appear to be trying to do, so you've essentially asked two questions. I'll deal with that one in the question title first:
how can a base class update a derived(child) class?
It can't; it doesn't even know it exists. The derived class knows the base class exists though, so you can use that instead
One way is to have the derived class override the setting function of the base class:
class MyBase{
int _myField;
virtual void SetMyField(int val){
_myField = val;
}
}
class MyDerived:MyBase{
string _myOtherField;
override void SetMyField(int val){
base.SetMyField(val);
_myOtherField = val.ToString();
}
}
In use, a variable of type MyBase holding an instance of type MyDerived, will set both values when you call SetMyField:
var mb = new MyDerived();
mb.SetMyField(1); //implementation on MyDerived is used, causing _myOtherField to be set
You might have the base class raise an event (or invoke a delegate) when it's property is set and the derived class subscribes to it
class MyBase{
int _myField;
event EventHandler<int> MyFieldUpdatedTo;
void SetMyField(int val){
_myField = val;
var e = MyFieldUpdatedTo;
e?.Invoke(this, val);
}
}
class MyDerived:MyBase{
string _myOtherField;
MyDerived(){ //constructor, or can also subscribe to event in the place that instantiates the MyDerived
base.MyFieldUpdatedTo += val => _myOtherField = val.ToString();
}
}
This is perhaps slightly unusual, though common to see in windows forms
However you arrange it, you need to leverage that the derived knows about the base but not the other way round, so anything done to the base needs to go via the derived, or via something that knows about both of them, or by creating a link from base to derived
In your specific case you're having a problem because the class that knows about both of your data items (the base class) only sets one of them
You could literally trigger the setting of the string by changing the value of the Public_herunterfahrenTimer to anything:
public void Minuten_Zu_Sekunden_Umrechnung()
{
_sekunden = (_minuten * 60);
Public_herunterfahrenTimer = ""; //any string, the value is not used
}
You could also put the setting of _sekunden into Public_herunterfahrenTimer and then set that property in the derived method
But structuring the code like this, and actually the code structure in general is very strange- we simply wouldn't write code like that. There is no need for a string property that duplicates information that is remembered in the _sekunden variable, and does do on the set, which naturally allows data to go out of sync
Instead you should perhaps just calculate the string in a get:
public class Zeiteinheit : ShutdownTime
{
public int Minuten
{
get { return _sekunden / 60; }
set { _sekunden = (value * 60); }
}
}
public class ShutdownTime
{
protected int _sekunden;
public string HerunterfahrenTimer
{
get { return $"-s -t {_sekunden}"; }
}
}
There is no possibility now for these to be out of sync; setting the minutes means the seconds are updated and the shutdown argument string will be generated when it is requested
note, I've also fixed your code up to regular C# conventions- strive to only use snake case on CONSTANTS_LIKE_THIS, don't prefix public things with "Public" and be consistent with the leading underscores on field names; all or none
So I have the method that makes the factorial of a number but I don't want to make it every time I need it. I want to make it global so I can call it everytime I need it.
double factorial(int i)
{
int input = i;
double result = 1;
if (i == 0)
{
result = 1;
return result;
}
else
{
while (input != 1)
{
result = result * input;
input = input - 1;
}
return result;
}
}
What is does is that if gives you the factorial of a number in my Windows Form but I use it in all my windows forms so I copy this method in each class.
p = factorial(i))
That's how I call it and it works perfectly but is there a way to make it it's own class so I don't have to copy it to every one of my windows Forms and if so how would I call it?
I copy this method in each class. Is there a way to make it it's own class?
Absolutely! Since your method does not depend on fields of your class, make it static, and add it to a class that hosts math helper methods, for example
public static class MathHelpers {
public static double Factorial(int i) {
...
}
}
Note that I also marked the class static to ensure its users that they never need to create an instance of it. Essentially, such class becomes a holder of static methods.
You call the method from your form as follows:
double f = MathHelpers.Factorial(5);
Generally you can add this to a class and make the method public static.
Say I have a class like this for calculating the cost of travelling different distances with different modes of transportation:
public class TransportationCostCalculator
{
public double DistanceToDestination { get; set; }
public decimal CostOfTravel(string transportMethod)
{
switch (transportMethod)
{
case "Bicycle":
return (decimal)(DistanceToDestination * 1);
case "Bus":
return (decimal)(DistanceToDestination * 2);
case "Car":
return (decimal)(DistanceToDestination * 3);
default:
throw new ArgumentOutOfRangeException();
}
}
This is fine and all, but switch cases can be a nightmare to maintenance wise, and what if I want to use airplane or train later on? Then I have to change the above class. What alternative to a switch case could I use here and any hints to how?
I'm imagining using it in a console application like this which would be run from the command-line with arguments for what kind of transportation vehicle you want to use, and the distance you want to travel:
class Program
{
static void Main(string[] args)
{
if(args.Length < 2)
{
Console.WriteLine("Not enough arguments to run this program");
Console.ReadLine();
}
else
{
var transportMethod = args[0];
var distance = args[1];
var calculator = new TransportCostCalculator { DistanceToDestination = double.Parse(distance) };
var result = calculator.CostOfTravel(transportMethod);
Console.WriteLine(result);
Console.ReadLine();
}
}
}
Any hints greatly appreciated!
You could do something like this:
public class TransportationCostCalculator {
Dictionary<string,double> _travelModifier;
TransportationCostCalculator()
{
_travelModifier = new Dictionary<string,double> ();
_travelModifier.Add("bicycle", 1);
_travelModifier.Add("bus", 2);
_travelModifier.Add("car", 3);
}
public decimal CostOfTravel(string transportationMethod) =>
(decimal) _travelModifier[transportationMethod] * DistanceToDestination;
}
You could then load the transportation type and it's modifier in a configuration file instead of using a switch statement. I put it in the constructor to show the example, but it could be loaded from anywhere. I would also probably make the Dictionary static and only load it once. There is no need to keep populating it each time you create a new TransportationCostCalculator especially if it isn't going to change during runtime.
As noted above, here is how you could load it by a configuration file:
void Main()
{
// By Hard coding.
/*
TransportationCostCalculator.AddTravelModifier("bicycle", 1);
TransportationCostCalculator.AddTravelModifier("bus", 2);
TransportationCostCalculator.AddTravelModifier("car", 3);
*/
//By File
//assuming file is: name,value
System.IO.File.ReadAllLines("C:\\temp\\modifiers.txt")
.ToList().ForEach(line =>
{
var parts = line.Split(',');
TransportationCostCalculator.AddTravelModifier
(parts[0], Double.Parse(parts[1]));
}
);
}
public class TransportationCostCalculator {
static Dictionary<string,double> _travelModifier =
new Dictionary<string,double> ();
public static void AddTravelModifier(string name, double modifier)
{
if (_travelModifier.ContainsKey(name))
{
throw new Exception($"{name} already exists in dictionary.");
}
_travelModifier.Add(name, modifier);
}
public double DistanceToDestination { get; set; }
TransportationCostCalculator()
{
_travelModifier = new Dictionary<string,double> ();
}
public decimal CostOfTravel(string transportationMethod) =>
(decimal)( _travelModifier[transportationMethod] * DistanceToDestination);
}
Edit: It was mentioned in the comments that this wouldn't allow the equation to be modified if it ever needed to change without updating the code, so I wrote up a post about how to do it here: https://kemiller2002.github.io/2016/03/07/Configuring-Logic.html.
It looks to me like any solution based on your current method is flawed in one critical way: No matter how you slice it, you're putting data in your code. This means every time you want to change any of these numbers, add a new vehicle type, etc., you have to edit code, and then recompile, distribute a patch, etc.
What you really should be doing is putting that data where it belongs - in a separate, non-compiled file. You can use XML, JSON, some form of database, or even just a simple config file. Encrypt it if you want, not necessarily needed.
Then you'd simply write a parser that reads the file and creates a map of vehicle type to cost multiplier or whatever other properties you want to save. Adding a new vehicle would be as simple as updating your data file. No need edit code or recompile, etc. Much more robust and easier to maintain if you plan to add stuff in the future.
Sounds like a good candidate for dependency-injection:
interface ITransportation {
decimal CalcCosts(double distance);
}
class Bus : ITransportation {
decimal CalcCosts(double distance) { return (decimal)(distance * 2); }
}
class Bicycle : ITransportation {
decimal CalcCosts(double distance) { return (decimal)(distance * 1); }
}
class Car: ITransportation {
decimal CalcCosts(double distance) { return (decimal)(distance * 3); }
}
Now you can easily create a new class Plane:
class Plane : ITransportation {
decimal CalcCosts(double distance) { return (decimal)(distance * 4); }
}
Now create a constrcutor for your calculator that expects an instance of ITransportation. Within your CostOfTravel-method you can now call ITransportation.CalcCosts(DistanceToDestination).
var calculator = new TransportationCostCalculator(new Plane());
This has the advantage that you can exchange your actual transportation-instance without any code-change to your TransportationCostCalculator-class.
To complete this design you might also create a TransportationFactory as follows:
class TransportationFactory {
ITransportation Create(string type) {
switch case "Bus": return new Bus(); break
// ...
}
Which you call like
ITransportation t = myFactory.Create("Bus");
TransportationCostCalculator calculator = new TransportationCostCalculator(t);
var result = myCalculator.CostOfTravel(50);
You could define an abstract class like this, and have each TransportationMethod extend the abstract class:
abstract class TransportationMethod {
public TransportationMethod() {
// constructor logic
}
abstract public double travelCost(double distance);
}
class Bicycle : TransportationMethod {
public Bicycle() : base() { }
override public double travelCost(double distance) {
return distance * 1;
}
}
class Bus : TransportationMethod {
public Bus() : base() { }
override public double travelCost(double distance) {
return distance * 2;
}
}
class Car : TransportationMethod {
public Car() : base() { }
override public double travelCost(double distance) {
return distance * 3;
}
}
So in your actual method call, it could be rewritten like this:
public decimal CostOfTravel(TransportationMethod t) {
return t.travelCost(DistanceToDestination);
}
You could use a strategy class for each type of travel. But, then you'd probably need a factory to create the strategy based upon the transport method which would likely have a switch statement to return the appropriate calculator.
public class CalculatorFactory {
public static ICalculator CreateCalculator(string transportType) {
switch (transportType) {
case "car":
return new CarCalculator();
...
public class CarCalculator : ICalculator {
public decimal Calc(double distance) {
return distance * 1;
}
}
....
You can make a Dictionary that returns a multiplier based on transport.
public class TransportationCostCalculator
{
Dictionary<string, int> multiplierDictionary;
TransportationCostCalculator ()
{
var multiplierDictionary= new Dictionary<string, int> ();
dictionary.Add ("Bicycle", 1);
dictionary.Add ("Bus", 2);
....
}
public decimal CostOfTravel(string transportMethod)
{
return (decimal) (multiplierDictionary[transportMethod] * DistanceToDestination);
}
I think the answer is some kind of database.
If you use some, the TransportCostCalculator ask the database for the multiplayer to the given transportmethod.
The database may be a text-file or an xml or an SQL-server. Simply a key-value-pair.
If you want to use code-only there is - tmo - no way to avoid the translation from transportmethod to multiplayer (or cost). So some kind of swicht is needed.
With the database you put the dictionary out of your code and you must not change your code to apply new transportmethods or change the values.
This is a case for the strategy design pattern. Create a base class, say TravelCostCalculator, then develop classes for each mode of travel you will consider, each overriding a common method, Calculate(double). You can then instantiate the specific TravelCostCalculator as needed using the factory pattern.
The trick is in how to construct the factory (without a switch statement). The way I do this is by having a static class constructor (public static Classname() - not an instance constructor) that registers each strategy class with the factory in a Dictionary<string, Type>.
Since C# does not run class constructors deterministically (like C++ does in most cases) you have to explicitly run them to ensure they will run. This could be done in the main program or in the factory constructor. The downside is that if you add a strategy class, you must also add it to the list of constructors to be run. You can either create a static method that must be run (Touch or Register) or you can also use System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor.
class Derived : Base
{
public static Derived()
{
Factory.Register(typeof(Derived));
}
}
// this could also be done with generics rather than Type class
class Factory
{
public static Register(Type t)
{
RegisteredTypes[t.Name] = t;
}
protected Dictionary<string, Type t> RegisteredTypes;
public static Base Instantiate(string typeName)
{
if (!RegisteredTypes.ContainsKey(typeName))
return null;
return (Base) Activator.CreateInstance(RegisteredTypes[typeName]);
}
}
I prefer to use Enum for that like this:
public enum TransportMethod
{
Bicycle = 1,
Bus = 2,
Car = 3
}
And use it like this method:
public decimal CostOfTravel(string transportMethod)
{
var tmValue = (int)Enum.Parse(typeof(TransportMethod), transportMethod);
return DistanceToDestination * tmValue;
}
Note that above method is case-sensitive, So you can capitalize first char;
Related Answer
It was said before but i want to give related topic another shot.
This is a good example for reflection.
"Reflection objects are used for obtaining type information at runtime. The classes that give access to the metadata of a running program are in the System.Reflection namespace."
By using reflection, you will avoid compiling code if another switch type such as train is wanted to add the program. You will solve the problem on the fly by using a config file.
I recently solved a similar problem with strategy patttern, by using dependency injection but I still end up with switch statement. It doesnt solve your problem this way. Method suggested by tyson still needs recompile if a new type added to dictionary.
An example of what i am talking about:
Dynamic Loading of Custom Configuration XML using Reflection in C# :
http://technico.qnownow.com/dynamic-loading-of-custom-configuration-xml-using-reflection-in-c/
Define a look up table array 3 by 2.
Look up rate value in array cell adjacent to transport type.
Calculate cost based on rate.
I am trying to inherit abstract members from a derived class and it is not working.
I have set the class as abstract such as
Now my main program says the same thing about the CalculateWeeklyPay() and I shouldn't need it in my main class. How can I fix that?
// Pay method
public double CalculateWeeklyPay(double Hours, double Wage)
{
return Hours * Wage;
}
The parameter list to CalculateWeeklyPay is hiding the class members Hours and Wage. I suspect you want this instead:
// Pay method
public double CalculateWeeklyPay()
{
return Hours * Wage;
}
In fact, I would go a step further and make it a read-only property instead:
// Pay method
public double WeeklyPay
{
get { return Hours * Wage; }
}
output += "\n\t Weekly Pay:\t" + CalculateWeeklyPay().ToString("C2");
You define public double CalculateWeeklyPay(double Hours, double Wage),but in this function there are not two double number.It is wrong.
public override double CalculateWeeklyPay(){...}
abstract is like virtual except that a derived class must either override it or else must become abstract itself.
output += "\n\t Weekly Pay:\t" + CalculateWeeklyPay().ToString("C2");
CalculateWeeklyPay is expecting 2 arguments: Wage and Hours. Remove those arguments from the definition and it will work:
public override double CalculateWeeklyPay()
{
...
}
I have 3 classes named maths, alphabets and main. The Maths Class contains Add function and alphabet class contains a function same as Maths class. But the third class is for calling the function which is used for calling the above functions defined in the above classes.
How it will work?
If the functions are static you'll have to explicitly tell which class they belong to - the compiler will be unable to resolve otherwise:
Maths.Add();
If they are not static the compiler will determine this based on the object type:
Maths maths = new Maths();
maths.Add(); // the necessary class and function will be resolved automatically
Is this what you mean?
public class Maths
{
public Maths() { }
public Double Add(Double numberOne, Double numberTwo)
{
return numberOne + numberTwo;
}
}
public class Alphabet
{
public Alaphabet() { }
public String Add(Char characterOne, Char characterTwo)
{
return characterOne.ToString() + characterTwo.ToString();
}
}
public void Main()
{
Alphabet alaphatbet = new Alphabet();
String alphaAdd = alphabet.Add('a', 'b'); // Gives "ab"
Maths maths = new Maths();
Double mathsAdd = maths.Add(10, 5); // Gives 15
}
By using an interface that defines an Add function and having Math and alphabets implement that interface.
C# programs do not contain "functions", but instead methods, which are attached to classes. So you call Math.Add or Alphabet.Add. Conflicting function names do not exist, in C#, for that reason. Conflicting class names are resolved by name spaces.