C#: Inherit from Child-Class to Base-Class - c#

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

Related

how to handle lots of separate ui commands c#, how to get them, initialize them and execute them

I have fairly complicated ui system that i want to simplify. What I want is to make separate classes with command and fluent builder pattern that which instances I will create at the beginning of the app and then execute when needed, something like this:
public interface IGuiCommand
{
void Execute();
void Execute(Action onComplete = null);
}
public class GuiCommandBuilder : IGuiCommand
{
public void Execute()
{
}
public void Execute(Action onComplete = null)
{
}
}
public class GuiCommandTest : GuiCommandBuilder
{
private int _id;
public GuiCommandTest()
{
}
public GuiCommandTest Setup(int id)
{
_id = id;
return this;
}
}
so I can do this:
// create command
var GuiRoomSelectionCommand = new GuiCommandTest();
// setup and execute (I have to provide additional data in order
// command to work correctly, some commands don't need additional data)
GuiRoomSelectionCommand
.Setup(223)
.Execute(() =>
{
});
The problem I am having is that I want to create all commands
at the start of the app and store them for later easy access, but I can't just
store them as IGuiCommand since I will need a concrete instance in order to setup the
concrete commands? How to do that, or if any other setup is better approach?
I want that others can easily see what commands are there and how to add more of them
if needed or easily modify the existing ones in separate classes so that main controller
doesn't change to much but only specific commands
Define an ICommandParameter interface to indicate the name of the parameter and its current value.
You can create different types of parameters by implementing this interface:
public ICommandParameter
{
string Name {get;set;}
object ObjectValue {get;set;}
}
public IDoubleParameter : ICommandParameter
{
double MinValue {get;set;}
double MaxValue {get;set;}
double Number {get;set;}
int DecimalsCount {get;set;}
}
public IBoolParameter : ICommandParameter
{
bool Checked {get;set;}
}
public IAnimalsParameter : ICommandParameter
{
Animal Animal {get;set;} // Animal is an enum with a list of values
}
Now, your IGuiCommand can have a list of ICommandParameter that you can initialize in the constructor of your command.
In GuiCommandBuilder (or in other class if you consider) you can manage the parameters. You have access to the command parameters and show/update using some Forms.
For example, in your GuiRoomSelectionCommand you can access to the parameters list, with a simgle parameter "Number of rooms" that you can see (you can check/try cast) that implements IDoubleParameter with this values:
Name = "Number of rooms"
ObjectValue = 2
MinValue = 1
MaxValue = 10
Number = 2 // Usually a cast of ObjectValue interface
DecimalsCount = 0
You can create a Form in which you add some controls depending of parameters type. For previous example, you can add a Label for Name and a NumericUpDown for the value (settings decimals, minimum and maximum). You initialize the numeric with the Number property. And when you click Ok in the dialog, you can update de Number property with the numeric value.
For any Enum property, you can add a ComboBox to show/edit it's value. For a bool property, a CheckBox and so on.
You need spend some time to create the controls for any type of property to manage but, at the end, most of properies are of basic types. There aren't lots of controls.

Check if object is defined after initialization in c#

I have the following object (class).
namespace Temp.Models
{
public class CurrentClass
{
private double _firstCoefficient;
private double _secondCoefficient;
public double FirstCoefficient
{
get { return _firstCoefficient; }
set { _firstCoefficient= value; }
}
public double SecondCoefficient
{
get { return _secondCoefficient; }
set { _secondCoefficient= value; }
}
}
}
The following class utilizes the above object and therefore initializes the object as follows:
namespace Temp.Models
{
public class MainClass
{
private CurrentClass _currentClass = new CurrentClass();
public CurrentClass CurrentClass
{
get { return _currentClass; }
set { _currentClass = value; }
}
}
}
At some point if certain conditions are met I would define the variables as follows:
MainClass currentObject = new MainClass();
//if conditions are met
currentObject.CurrentClass.FirstCoefficient = 0;
currentObject.CurrentClass.SecondCoefficient = 5;
But what if the conditions are never met and I never define the above variables. How and/or what is the best way to check if the object was never defined?
I can do the following check:
if(currentObject.CurrentClass.FirstCoefficient != 0 && currentObject.CurrentClass.SecondCoefficent != 0)
But the values can be defined as 0...So I am not sure how to go about this.
Any help is much appreciated!
These are some principles that can be used for solving the problem with description, samples and brief evaluation/opinion.
1. Parametrization through constructors
According to OOP principles, a constructor is method used to initialize an object to a valid state. The concept of immutability takes this even further, disallowing any changes, completely avoiding invalid state.
There is also a possibility of compromise where the API of an object disallows invalid states.
With this concept, you would arrive to:
namespace Temp.Models
{
public class CurrentClass
{
public double FirstCoefficient { get; private set; }
public double SecondCoefficient { get; private set; }
public CurrentClass(double firstCoefficient, double secondCoefficient)
{
FirstCoefficient = firstCoefficient;
SecondCoefficient = secondCoefficient;
}
// if mutability is required - this is needless as the constructor is
// the same but if there was more complex state, methods like this would make
// sense, mutating only parts of the state
public void SetCoefficients(double firstCoefficient, double secondCoefficient)
{
FirstCoefficient = firstCoefficient;
SecondCoefficient = secondCoefficient;
}
}
}
Summary:
Each instantiation of CurrentClass is always in a valid state, avoiding a lot of consistency checks (improved encapsulation)
It takes more code to write (but you save a lot of other code due to the previous point)
You need to know the coefficients beforehand.
2. Using nullable types
Nullable types add the "additional" value to types, the "undefined" state. Reference types (class) are nullable by design while value types (struct) need to be marked nullable, either as Nullable<T> or with the shorthand T?.
This then allows the objects be in invalid state and be specific about it. This goes to the other end of consistency scale from immutability as an object with multiple nullable fields has many invalid states.
Sample code:
namespace Temp.Models
{
public class CurrentClass
{
public double? FirstCoefficient { get; set; }
public double? SecondCoefficient { get; set; }
}
}
Now this gets instantiated quite nicely and can be changed on the fly:
public CurrentClass CreateCurrentClass()
{
var currentClass = new CurrentClass { FirstCoefficient = 1.0 };
var secondCoefficient = RetrieveSecondCoefficient();
currentClass.SecondCoefficient = secondCoefficient;
return currentClass;
}
You'll however need validity checks everywhere the object is used.
public bool IsValid(CurrentClass currentClass)
{
// what if FirstCoefficient has value and SecondCoefficient doesn't,
// is that always an invalid state?
return currentClass.FirstCoefficient.HasValue
&& currentClass.SecondCoefficient.HasValue;
}
Summary:
Very little code is needed to have a DTO up and running
A lot of consistency checks (and related brain pain) are required to work with such model
Encapsulation is lacking - any method taking CurrentClass can alter its validity, therefore making the previous point even worse. This can be eased by usage of read-only interface passed where read-only access is required.
Summing up
There are many other means that usually lay in between the two aforementioned approaches. For example you can use one validity flag (SergeyS's response) per object and ease on the external validity checks but having more code in the class and the need of deeper thinking.
Personally, I prefer immutability. It's more monkey code to write but will definitely pay off down the road thanks to the clean design.
A complex system without immutability is very hard to reason about without extensive knowledge. This is especially painful when working in a team - usually each person only knows a part of the codebase.
The sad thing is that it's not always possible to have evertything immutable (e.g. viewmodels): then I tend to convert objects to an internal immutable model as soon as it's possible.
Given what you already wrote, I would add Initialize() method and Initialized property into your MainClass class. Something similar to this:
public class MainClass
{
private CurrentClass _currentClass = new CurrentClass();
public CurrentClass CurrentClass
{
get { return _currentClass; }
set { _currentClass = value; }
}
public bool Initialized {get; private set;}
public void Initialize()
{
this.CurrentClass.FirstCoefficient = 0;
this.CurrentClass.SecondCoefficient = 5;
this.Initialized = true;
}
}
Call Initialize() method where your conditions met.
Later in code you can just check if(currentObject.Initialized). Notice private setter for `Initialized' property, it will ensure this flag was not accidentally set by external code.
Depending on your needs, you can go further and pass parameters for initialization directly to Initialize() method as parameters.
You have several approaches, like force values to be correct in constructor or have another variable telling if object has no value yet, like System.Drawing.Point has static "Empty" property. But in this case of your simple object your main class is explicitly creating an instance of CurrentClass so at this point this object should be correct and coefficients should be set. If you rely on some other code to set those values to perform some other action later, it is out of scope of these two objects here.
Update: perharps sharing details of what the real problem is would be better, because I have a feeling trying to provide a simpified example ended up in hiding real problem.

C# Custom getter/setter without private variable

I learned c# recently, so when I learned to write properties, I was taught to do it like this:
public string Name { get; set; }
Auto properties are great! But now I'm trying to do something a little more complicated, so I need to write a custom pair of accessors.
private string _Name;
public string Name {
get { return _Name; }
set { _Name = value }
}
I know the compiler makes a private instance variable down in it's murky depths when one uses autos, but I'm spoiled and don't want that private variable sitting around looking pointless.
Is there a way to use custom accessors without a private variable?
Properties don't need backing variables (fields) at all. While they can be used for encapsulating simple fields you can also use them to access other data.
public Decimal GrandTotal { get { return FreightTotal + TaxTotal + LineTotal; } }
or
public string SomeStatus { get { return SomeMethodCall(); } }
If the goal is to simply encapsulate some field with a property you would need some sort of backing field if you are not using automatic properties.
The answer is No, you cannot do that.
It is because of recursion. (See line numbers 9 and 7):
Line 1 : public string Name
Line 2 : {
Line 3 : get
Line 4 : {
Line 5 : return FirstName + " " + LastName;
Line 6 : }
Line 7 : set
Line 8 : {
Line 9 : Name = value; // <-- Goes back to Line 7
Line 10 : }
Line 11 : }
No, I'm afraid not. The compiler is smart enough to make this happen for you on auto-generated properties, but with standard properties I imagine the logic behind something like that would end up getting in the way and doing more harm than good.
For example, what if I create a property like this...
public int SomeValue
{
get
{
return 0;
}
}
Would the compiler (with the feature you're looking for) create a backing private variable? Why? It doesn't need one.
Additionally, if the private value isn't created until compilation time, what are you going to reference in your code:
public string Name {
get { return _Name; }
set { _Name = value }
}
What is _Name? What if you have another value somewhere else called _Name? Then what would the compiler call the backing value for this property? What if I need two backing values? Would the compiler be smart enough for that?
public string Name
{
get
{
return string.Format("{0} {1}", _FirstName, _LastName);
}
set
{
// some parsing magic
}
}
It's been asked before, but I imagine the answer is going to continue to be "no" for the foreseeable future.
An auto-property is syntactic shorthand for simple direct member access. (And I imagine one of its driving forces was simply to try to get people to stop creating public values directly.) Properties can grow in complexity well beyond that very easily and I personally wouldn't want the compiler trying to figure out what I can easily just tell it to do.
I know this is an old question, but there is at least one other option here. I'm doing something similar to the below for my own app.
This might not exactly be for your use case, but it shows that a custom getter and setter can be used without a private instance variable. In this case, the getter and setter are shortcut or helper methods to access the Name property of the User for the Account.
We can let the value be set by doing Account.AccountUser.Name = "John Doe";, but sometimes that seems a bit clunky and it works against the idea of separation of concerns. Do we want someone using the Account class to know there's a User imbedded in it? If for some reason we don't, we now have a way to still update the User.Name even if we make AccountUser private.
In this case, AccountUser is public, but it doesn't have to be. When it's private, a Json or XML conversion utility (such as Newtonsoft) should ignore the AccountUser and show just the Name as if the Account were a flat model, instead of having multiple levels.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Account
{
public int Id { get; set; }
public User AccountUser { get; set; }
public string Name
{
get
{
return AccountUser.Name;
}
set
{
AccountUser.Name = value;
}
}
}

How can I override get and set methods for all properties in a class?

I have got several classes looking like the one below, and I need to do some checks in the get method and custom set methods. Adding the code in each get and set method makes everything look really messed up.
Is there a way I can override the get and set methods for all properties in an entire class?
public class Test
{
private DataRow _dr;
public Test()
{
_dr = GetData();
}
public string Name
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string Description
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string DescriptionUrl
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
}
}
private void VerifyAccess(string propertyname, string classname)
{
//some code to verify that the current user has access to update the property
//Throw exception
}
private DataRow GetData()
{
//Some code to pull the data from the database
}
}
I think what you need is a Proxy on your class, read about Proxy Pattern and Dynamic Proxies
Not directly, there isn't a way to do it with just a compiler. You'd have to generate your entire binary file, then post-process it with some external tool.
This post describes a somewhat similar issue; I hope it helps.
There's a variety of ways to do it.
One would be to create a proxy class (mentioned before), but that would require a lot of refactoring on your behalf.
Another way is with aspects. These do exactly what you're after (insert code based on a pre-requisite.. i.e. all get methods in a class that inherit from x). I ran into a similar problem (actually the exact same problem - checking for security on method calls), and couldn't find cheap/free aspect software that fulfilled my needs.
So, I decided to use Mono-Cecil to inject code before function calls.
If you're interested (it gets a bit messy dealing with IL codes) I can post an old copy of the source
You should extract common code to separate get/set methods, after that you'll be able to add common logic to your properties. By the way, I would do such extraction anyway to avoid copy/paste in the code.
Smth like this:
public string Name
{
get { return GetProperty(MethodBase.GetCurrentMethod()); }
set
{
SetProperty(MethodBase.GetCurrentMethod(), value);
}
}
private string GetProperty(MethodBase method)
{
return _dr[method.Name.Substring(4)].ToString();
}
private void SetProperty(MethodBase method, string value)
{
string methodName = method.Name.Substring(4);
VerifyAccess(methodName , this.GetType().Name);
_dr[methodName] = value;
}
This can be done with indirect value access, e.g. obj.PropA.Value = obj.PropB.Value + 1 -- you can even keep strong typing information. It can be implemented with either attributes or direct-instantiation.
// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;
// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);
Alternatively, perhaps using a template system such as TT4 may be a viable approach.
However, don't forget "KISS" :-)
I would love for someone to give a better answer for this.
I'm looking for an answer now… best idea I have had would be to define all the properties you want to have be validated as a generic class. For example:
public class Foo {
public String Name {
get{ return _Name.value; }
set{ _Name.value = value; }
}
private Proxy<String> _Name;
static void main(String[] args) {
Foo f = new Foo();
//will go through the logic in Proxy.
f.Name = "test";
String s = f.Name;
}
}
public class Proxy<T> {
public T value {
get {
//logic here
return _this;
} set {
//logic here
_this = value;
}
}
private T _this;
}

Accessing members in your own class: use (auto)properties or not?

I've created this "question" as a community-wiki, because there is no right or wrong answer. I only would like to know how the community feels about this specific issue.
When you have a class with instance variables, and you also created properties that are simply getters and setters for these instance variables, should you use the properties inside your own class, or should you always use the instance variable?
Having auto-properties in C# 3.0 made this an even harder decision.
Using properties:
public class MyClass
{
private string _name;
// could be an auto-property of-course
public string Name { get { return _name; } set { _name = value; } }
public void Action()
{
string localVar = Name;
// ...
Name = "someValue";
// ...
}
}
Using instance variables:
public class MyClass
{
private string _name;
public string Name { get { return _name; } set { _name = value; } }
public void Action()
{
string localVar = _name;
// ...
_name = "someValue";
// ...
}
}
(for those who hate member prefixes, I apologize)
Personally, I always use the latter (instance variables), because I feel that properties should only be used by other classes, not yourself. That's why I mostly stay away from auto-properties as well.
Of course, things change when the property setter (or getter) does a little more than just wrapping the instance variable.
Are there compelling reasons to pick one or the other?
I always use instance variables as well. The reason is because properties might be doing stuff like validating arguments (like in a setter) for not null or not empty. If you're using the variable inside your class code, there's no need to go through the extra overhead of those checks (assuming you know the variable value is valid). The properties could be doing other things as well (logging, for example), that are important for the public API, but not for internal usage, so again, it's better to avoid the overhead and just use the instance variable in my opinion.
I think it becomes more difficult to change the internal implementation if the code uses its own public interface.
Difficult to explain but consider these expressions:
mTotalPrice = mPrice * mQuantity;
mTotalPrice = Price * Quantity;
What to do in the second expression if I need to change the internals to express all prices in € instead of $ (without affecting the public interface which still uses $)?
One solution is to make the expression more complex by adding the opposite of the change in the property.
mTotalPrice = Price / Rate * Quantity
The other solution is to start to use the private field instead.
mTotalPrice = mPrice * Quantity
In the end you get a mix of private and public use. The only way to get consistent use is to always use the private field.
I don't like prefixing members either, but actually I find I can write something like this accidently and not spot it until run time. Which kinda tempts me to avoid using properties where they're not necessary... but I still do, currently!
Public String MyString
{
{ get { return this.MyString; } } //<== Stack Overflow
{ set { this.myString = value; } }
}
private String myString;
I think that there is no difference between these two approaches.
Auto-implemented properties is just a quick way to access private members which are created any way.
Example from MSDN:
class Customer
{
// Auto-Impl Properties for trivial get and set
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
// Constructor
public Customer(double purchases, string name, int ID)
{
TotalPurchases = purchases;
Name = name;
CustomerID = ID;
}
// Methods
public string GetContactInfo() {return "ContactInfo";}
public string GetTransactionHistory() {return "History";}
// .. Additional methods, events, etc.
}
99% of the time I use the property rather then the instance variable. In the past, I've worked with a lot of code that used the instance variable and when there was a bug associated with that variable, I had to put a breakpoint on every line of code that referenced it.
I decided to use properties instead, either public or private, to wrap around the instance variable. Doing this means that I only have to put a breakpoint in the getter/setter of the property if I need to debug an issue with the instance variable, rather then having (potentially) a lot of breakpoints scattered all over the code.

Categories

Resources