Hey Guys i could need some Help here.
I'm supposed to implement an abstract class with some attributes (that I already have). Now I'm supposed to write a constructor that initializes the attributes and add getters and setters. Here I am stuck can someone tell me how to implement this?
Here is my abstract class
namespace Personalverwaltung {
public abstract class Person
{
public string Name;
public string Adresse;
public int Hausnummer;
public int PLZ;
public string Ort;
}
}
There are no Getters and Setters in C# (at least they are not advised as in i.e. Java implementations), there are only properties.
Take a look here to help you: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
Example:
private double _seconds;
public double Hours
{
get { return _seconds / 3600; }
set {
if (value < 0 || value > 24)
throw new ArgumentOutOfRangeException(
$"{nameof(value)} must be between 0 and 24.");
_seconds = value * 3600;
}
}
For an example constructor, look here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors
Both articles will help you learn when you implement them. There are enough examples and information to get you going. Good luck on your programming journey.
Related
For a class Foo I need an int-like property SanityCheckPeriod that allows only values between two limits (say 1 till 7).
What is an elegant way to implement this requirement - maybe with attributes in a declarative manner?
(because I need that pattern multiple times and for expressiveness it would be great to see the limits directly attached to the property.
The idea would be something like this:
public class Foo
{
[RangeAttribute(min: 1, max: 7)]
public Period SanityCheckPeriod { get; }
...
}
public class Period
{
private int _days;
private int _max;
private int _min;
public int Days
{
get => _days;
private set
{
if (_min <= value)
throw new ArgumentExcpetion($"Period must be equal or larger than {_min} day(s).");
if (value <= _max)
throw new ArgumentExcpetion($"Period must be equal or smaller than {_max} days.");
_days = value;
}
}
public Period(int days)
{
// access the RangeAttribute here
// how to do?
// and set _min and _max
}
}
[AttributeUsage(AttributeTargets.Property)]
public class RangeAttribute : Attribute
{
public int Min { get; }
public int Max { get; }
public RangeAttribute(int min, int max)
{
Min = min;
Max = max;
}
}
If you ONLY need exact and wellknown sanity checks, then you could opt for extension methods:
public static void SanityCheckPeriod(this int value, int min, int max)
{
//check sanity
}
An elegant way to achieve this in general is with Aspect Oriented Programming which C# doesn't support OOTB. PostSharp is well documented (I'm not affiliated with them) but I don't know if any of their licenses satisfies your needs.
If bringing your own aspect is what you prefer, then you will have to accept that you need to access your object via an "interpreter".
I've seen an example where all objects are accessed via a factory where all objects returned are wrappers which scans the object for custom attributes. So that's a way where BYO aspect oriented code is preferred and where the gritty code is hidden in a single place leaving the rest of the code elegant, then that's a solution as well.
I'm assuming you're not working in the context of a framework that already provides validation conventions (as shown in MVC's Part 6: Using Data Annotations for Model Validation).
I'd go for something as the following.
public int Days
{
get => _days;
private set {
Ensure(1,7);
_days = value;
}
}
private void Ensure(int min, int max, [System.Runtime.CompilerServices.CallerMemberName] string memberName)
{
if (_min < value)
throw new ArgumentExcpetion($"'{memberName}' must be equal or greater than {min}.");
if (value < max)
throw new ArgumentExcpetion($"'{memberName}' must be equal or smaller than {max}.");
}
(Please note I adjusted <= and >= to match the error messages.)
With #rzmoz hint it was so easy:
Install PostSharp Tools for Visual Studio
Add NuGet packages
PostSharp.Patterns.Model with the RangeAttribute
PostSharp with the code weaving compiler
Apply the RangeAttribute to the property
[Range(1, 7)]
public int SanityCheckPeriod { get; internal set; }
Compile the stuff and everything works as expected
Tip: the property cannot be read-only and with private setter modifier R# complains Auto-property can be made get-only and recommends to remove it. But then the weaving will not work. Instead of suppressing this hint I switched to internal modifier which will not produce that R# hint.
I know that C# 8 is still under heavy development but I was concerned/excited about the default interfaces announcement. The examples I've seen all are represented like so:
public interface IMyDefaultInterFace
{
public int SomeDefaultFunction(int charge, int multiplier)
{
return charge * multiplier;
}
}
This is great but what I wonder (and hope) is that this will be possible as well:
public interface ISomeOtherInterface
{
int charge { get; set; }
}
public interface IMyDefaultInterFace : ISomeOtherInterface
{
int SomeDefaultFunction(int multiplier)
{
return charge * multiplier;
}
}
Does anybody know if this is the plan? I know there's some potential complexities involved due to scoping or whatnot but the former doesn't seem to offer any significant advantages while the latter provides some powerful possibilities.
Like I said I know it's early. Maybe some MS lurker has some inside info?
I've been programming in C# (as well as a few other languages) for some time now, but just recently decided that I should start writing custom classes to get a better feel for Object-Oriented Programming. To that end, I started with a base class of Vehicle, and some derived classes, to work on inheritance.
What I'm trying to do here is set up some default values and logic in the base calss of Vehicle, while having the derived classes implement some information which determines the differences. For example, while I set up the _wheelsNumber, _motorType, and _horsePower variables and logic in the base class, I would have each class (Car, Truck, Semi, Moped, etc.) set its _wheelsNumber and trigger the flow of logic to calculate out the rest of the properties.
However, I'm not sure I've built my classes in the right fashion to achieve those ends. I'm not clear on whether I'm even remotely doing the right things with my construcor and my get/set accessors (as I don't want the user to be choosing things like how many wheels a Car has, I haven't declared set accessors). One thing I think I've noticed is that the user would have to ask the program for the number of wheels before the motor type and that before the horsepower. I think this is because they're not calculated within the constructor, but I'm not certain.
Anyone clarity would be vastly appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VehicleClasses
{
abstract public class Vehicle
{
protected const int smallMotor = 1;
protected const int mediumMotor = 3;
protected const int largeMotor = 5;
protected const int largerMotor = 7;
protected const int hugeMotor = 9;
protected const int wrongMotor = 9001;
public Vehicle()
{
_horsePower = (_motorType * _motorType) * 8;
}
protected int _wheelsNumber;
public int wheelsNumber
{
get
{
return _wheelsNumber;
}
}
protected int _motorType;
public int motorType
{
get
{
if (_wheelsNumber < 4)
{
_motorType = smallMotor;
}
else if (_wheelsNumber >= 4 && wheelsNumber <= 6)
{
_motorType = mediumMotor;
}
else if (_wheelsNumber > 6 && wheelsNumber < 10)
{
_motorType = largeMotor;
}
else if (_wheelsNumber >= 10 && wheelsNumber < 18)
{
_motorType = largerMotor;
}
else if (_wheelsNumber >= 18)
{
_motorType = hugeMotor;
}
else
{
_motorType = wrongMotor;
}
return _motorType;
}
}
protected int _horsePower;
public int horsePower
{
get
{
return _horsePower;
}
}
}
}
This is a common misapplication of inheritance. Subclasses should extend behavior, not just modify the values of state.
In your example, there is only one free variable, the number of wheels. Everything else is a derived trait based on that. Change the constructor of vehicle to take the number of wheels as an argument, then (if desired) you can add public static methods to the class like "CreateMotorcycle()" that create a vehicle with the correct number of wheels.
Alternate Suggested Exercise
Like I mentioned before, inheritance is useful when you want to extend behavior. For example, lets say you have an "Employee" base class. To keep things simple, lets say each Employee has one junior and one senior.
Whenever an employee wants time off, they have to ask their senior, but not every employee can approves. The request has to get passed up the chain until it reaches a "Manager", which is a derived instance.
Flipping it around, lets say the most senior employee is the owner. When he wants the company to do something, he doesn;t do it himself. He sends the command down the chain. Each layer might modify what needs to be done. For example, the owner says it needs to be done in 365 days, each manager says it has half the time he was told, and the worker completes the task.
Each "class" in these examples (Worker/Manager/Owner) behave differently when the same method is called. But having them all implement the same base class makes it easy to chain them together! this is a variant on the "Chain of Responsibility" and "Decorator" patterns.
Trying to decipher an appropriate OO design to implement. The basic scenario is that you have a PstnNumber which is essentially a 10 digit phone number that always starts with 0 (e.g. 0195550000). A rule has been introduced to allow auto-correcting of a number if the leading 0 is missing (e.g. 195550000).
START EDIT
I realised the original question may have been misunderstood (thankyou kindly to those whom have answered already), so I have edited to try and better explain the scenario.
END EDIT
I started playing with some preliminary concepts and then thought I would ask if there was a more appropriate way to go or do one of these suffice (on some level)?
Concept 1
public class PstnNumber
{
public virtual string Number { get; set; }
public PstnNumber() { }
public PstnNumber(string number)
{
this.Number = number;
}
}
public class AutoFormattedPstnNumber : PstnNumber
{
public override string Number
{
get { return base.Number; }
set { base.Number = value.PadLeft(10, '0'); }
}
public AutoFormattedPstnNumber() : base() { }
public AutoFormattedPstnNumber(string number)
{
this.Number = number;
}
}
Concept 2 (removed)
Concept 3
public class PstnNumber
{
public bool AutoCorrect { get; set; }
private string number;
public virtual string Number
{
get { return (this.AutoCorrect) ? this.number.PadLeft(10, '0') : this.number; }
set { this.number = value; }
}
public PstnNumber() : this(false) { }
public PstnNumber(bool autoCorrect)
{
this.AutoCorrect = autoCorrect;
}
public PstnNumber(string number) : this(false)
{
this.Number = number;
}
public PstnNumber(string number, bool autoCorrect) : this(autoCorrect)
{
this.Number = number;
}
}
I think Concept 1 may violate the Liskov Substitution rule because the subclass changes the behaviour of the Number property (happy to learn if I've misunderstood that).
Any alternative suggestions would be received happily.
do you have to do the autoformatting when the object is instantiated? If not,
what about:
public class PstnNumber
{
public virtual string Number { get; set; }
public PstnNumber() { }
public PstnNumber(string number) { this.Number = number; }
public AutoFormatNumber { get { return Numer.PadLeft(10, '0'); } }
}
avoid getter-setter-surprise
Avoid getters returning a different value than the one accepted by the setter. Imagine the following snippet:
if (input.Value != current.Number)
{
NumberChangedAgain = true;
current.Number = input.Value;
}
A simple solution would be to make PstnNumber immutable:
temp = PstnNumber.FromString(input.Value);
if (temp != current) { ... }
canonical format
If some data has different representations, there is a lot of advantage to storing it in a canonical representation, and move the format conversions to factory functions and getters / formatters. For example, you don't need to test comparison for short vs. long, long vs. short, short vs. short, long vs. long.
different aspects
Do you need the distinction between an "autoformatted" and a "normal" number, or is this merely a question of input and output - i.e.
does display format (short or long) depend on how the number was entered, or on where it is displayed?
is 0195550000 == 195550000 ?
I'd prefer to fold both classes into one if possible (i.e. when "entered with or without 0 can be forgotten"):
public class PstnNumber
{
private string m_number; // always in long format
public static PstnNumber(string s) { ... } // accepts short and long form
public string Number { get { return m_number; } }
public string AutoFormatted { { get { ... } }
}
Otherwise I'd go with Option 3, but always store the long format in m_number.
In Option 1 and Option 2, you aren't preserving the original number anyway, rendering the subclass worthless (except to know that it was autoformatted at some point, which doesn't seem like useful information). The alternative to make these Options more useful would be to format on Get instead of Set.
Option 3 is therefore the preferred pattern out of these three options, but I would also ask - why can't the PstnNumber also simply detect the number of digits, and autoformat accordingly?
If you follow the rules - there is one that says that "each routine (read class) should do only one thing and do it well".
According to that I would make PstnNumber just hold the number, and create some sort of factory that produces the right number.
Doing both in the same class means that you are weaving domain logic and representation. I prefer them separated.
I'd ask why your class name is so cryptic. "Number" is clear to me, and "P" suggests "phone", but what's the "stn" telling me? A few extra keystrokes would make this class more self-documenting.
I'd also ask about the logic of a default constructor that does not initialize the underlying data members to some value. I think a default constructor should have a sensible default value if possible.
I feel like option 1 is overkill. I don't think inheritance is making this model clearer or better. I don't see how it breaks Liskov substitution, which demands that you can use the subclass in any situation that calls for a base class. The methods map 1:1 as far as I can see. How is Liskov violated?
Option 2 says these are two separate classes with no relationship. That doesn't seem right to me.
All this work suggests that your problem will require that you use both classes. You'll have situations where the leading zero is NOT required and others where it is. Is that true? Or are you always going to require the leading zero?
I don't care for any of your options. I'd prefer an interface or a static factory or even modifying the class you have to anything you've suggested. It feels like a mere formatting issue. Do you store the number with the leading zero? If not, maybe it's just a view concern.
Do you have a really strong reason to have a setter and not have your members final? If not, that's probably a bigger problem than any other variation between the three.
So I'd go for a stateless #3 which means making the number final and gettng rid of the autoFormat variable.
For simplicity I'd just have a getNumberRaw and getNumberFormatted
Better yet, you could have getNumberRaw and getNumber(formatType) where formatType actually contains the code that formats the number since the format may change again in the future and combining formatting (view) with your phone number (model) isn't optimal.
(PS/EDIT): just the fact that a phone number can change is NOT a good reason to have a setter! Creating a new phone number object and replacing the old one will almost always work!
I am not familiar with c#, but I'd do this:
public class PstnNumber {
readonly string number;
public PstnNumber(string number) {
this.number = number;
}
public string getNumber() {
return number;
}
static public PstnNumber createNumber(string number) {
return new PstnNumber(number.PadLeft(10, '0'));
}
}
Of course if I knew how Properties work, I'd probably do it differently :)
I would go with a much simpler version, overriding the ToString method, or even, creating an ToString overload that receives the bool parameter indicating that the number should be formatted.
If I have a private variable that I want to have some internal validation on, and I want to keep that validation in one place, I put it behind a getter/setter and only access it thorugh that getter/setter. That's useful when dealing with public properties, because the other code cannot access the private variable, but when I'm dealing with object inside the class itself, is there any way to enforce the getter/setter?
private int _eyeOrientation;
private int eyeOrientation
{
get
{
return _eyeOrientation;
}
set
{
if (value < 0)
{
_eyeOrientation = 0;
}
else
{
_eyeOrientation = value % 360;
}
}
}
The issue here being that the other functions in the class may accidentally modify
_eyeOrientation = -1;
which would throw the program into a tizzy. Is there any way to get that to throw a compiler error?
Sounds like you need a angle type.
// Non mutable Angle class with a normalized, integer angle-value
public struct Angle
{
public Angle(int value)
{
Value = value;
}
private angle;
public Value
{
get { return angle; }
private set { angle = Normalize(value); }
}
public static int Normalize(int value)
{
if (value < 0) return 360 - (value % 360);
return value % 360;
}
}
public class SomeClass
{
public Angle EyeOrientation { get; set; }
}
If you have a certain kind of value, like angles, money, weight or whatever, it is always a good praxis to make it a own type, even if the value itself is stored in a int, decimal etc. This type makes your interfaces clearer and typesafe. It is not the same if you expect an Angle or a integer value as argument of some method.
In general, you shouldn't worry about this. Class members can still use the properties, if you don't want to put the checking in the class itself.
If your class is getting so large that you no longer trust methods inside the class, I'd think that it's time to start refactoring and breaking this into smaller classes that are more easily managable.
You could possibly define it in a nested class.
public class NeedsEye
{
Eye _eye = new Eye();
public NeedsEye()
{
// now, here, any access to the property must be made through the
// _eye variable. The Eye class has access to any of the properties
// and members of the NeedsEye class, but the NeedsEye class has not
// any access to members of the Eye class.
}
private class Eye
{
private int _orientation;
public int Orientation
{
get { return _orientation; }
if (value < 0)
{
_eyeOrientation = 0;
}
else
{
_eyeOrientation = value % 360;
}
}
}
}
You can mark the field as obsolete so that the compiler will generate a warning if you try to access it, and then suppress that warning for the property getter/setter.
The warning codes that you'd need to suppress are CS0612 for the plain Obsolete attribute and CS0618 if the attribute has a custom message.
In general I'd consider this a bit of a hack and try to avoid it if possible. A better solution would be to comment the code appropriately and train your fellow developers so that they'll do the right thing.
[Obsolete("Please use the EyeOrientation property instead.")]
private int _eyeOrientation;
public int EyeOrientation
{
#pragma warning disable 612, 618
get
{
return _eyeOrientation;
}
set
{
_eyeOrientation = (value > 0) ? value % 360 : 0;
}
#pragma warning restore 612, 618
}
Just put your private attribute and public getters/setters into a private class.
Then only the getter and setter can access the private attribute.
It is overkill but would work. :)
Depending on your tools you could look into enforcing a coding convention not allowing direct access to a private member outside a get/set
Might be some more work but you won't have to create a series of wrapper classes.