When to use constructor? - c#

Im learning c# online, and I just finished an exercise, were I should create a class called "People" and create 5 variables that can make the peoples uniqe:
public string name;
public int age;
public double heigth;
public double weigth;
public string nationality;
public int shoeSize;
I also created a class called "Bank" and declaired 4 members:
int accountNumber;
string firstName;
string lastName;
string bankName;
then, I got the question: "If you think that the bank class is associated with one person (People class) how would you use the class "People" in the class for "Bank" ?
Now I clearly didnĀ“t understand what was being ment.. Any ideas`?
Edit: when do I need the constructor method?

That's not a constructor, that's trying to teach you that you can have classes you created as properties inside another class you create.
In their example, one person is per bank, so you could have the People class as a property called Person to signify who the account belongs to. You can do this by adding the following to your Bank class:
public People person { get; set; }
In terms of a constructor, you'd need one if you wanted to set some default properties. Consider this constructor for Bank:
public Bank()
{
accountNumber = 1;
firstName = "Default";
lastName = "Default";
bankName = "Default";
person = new People();
}
See that last line that creates person? If you removed that, but then tried to do this.person.name you'd get a NullReferenceException. That's because by default your person would have the value of null.

It could be as simple as:
public class People // I would call it person though, as People is plural
{
public int age;
public double heigth;
public double weigth;
public string nationality;
public int shoeSize;
}
public class Bank // I would call it BankAccount though
{
int accountNumber;
string firstName;
string lastName;
string bankName;
// The answer to the question:
People owner; // <-- Here the bank account has a reference to the People class,
// you provided in the constructor
// And if you need the constructor
public Bank(People owner, int accountNumber)// <-- This is the constructor
{
this.accountNumber = accountNumber;
this.owner = owner;
} // <-- The constructor ends here.
}

How about
public class Person
{
//A property for Name
//A property for Address
}
In another class a property for collection of Persons
public List<Person> People { get; set; }

Thats the way I would go:
public class Person
{
public int Age { get; set; } // I would use properties and public properties are
// starting with a great letter
public double Heigth { get; set; }
public double Weigth { get; set; }
public string Nationality { get; set; }
public int ShoeSize { get; set; }
}
public class BankAccount
{
private Person _person; // private field for the person object
public int AccountNumber { get; private set; } // public propertie for the account
// number with a private setter
// because normally you want to read
// that from the outside but not set
// from the outside
public string FirstName
{
get { return _person.FirstName; }
}
public string LastName;
{
get { return _person.LastName; }
}
public string BankName { get; set; }
public Bank(Person person, int accountNumber)
{
AccountNumber = accountNumber;
_person = person;
}
}
Please allways write down the access parameters from properties, methods etc.

Related

How to automatically create a default constructor which sets default values

Is there any way to auto generate a constructor which looks like this:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public User(int id, string name)
{
Id = 0;
Name = "";
}
}
Currently I am creating a constructor like that with the refactoring tool (CTRL + .):
public User(int id, string name)
{
Id = id;
Name = name;
}
and editing each line afterwards which is pretty cumbersome when you have 20 properties per class. Is there a better way to that?
(Maybe to define a code snippet, so that we can somehow read the class properties with reflection and define them as snippet parameters?)
If you have a class with 20 properties, why do you need a constructor with 20 parameters? Maybe have a sense, but I usually create constructors to initialize properties that are relevant, to simplify the code, not to set all properties.
For your class, you can set the default values when you define the property and all constructors will use this values as the default.
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = string.Empty;
// Here you can even omit the constructor
public User()
{
}
}
Another thing that maybe useful is define a constructor with X parameters and reuse this constructor in other constructors with less parameters:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public User()
: this(0, string.Empty)
{
}
public User(int id, string name)
{
Id = id;
Name = name;
}
}
You can replace this(0, string.Empty) for this(default, default) if you want use the default value of each type.
If you need object create with default value for properties. You can code like this:
public class User
{
public int Id { get; set; } = 0;
public string Name { get; set; } = "";
}
Purpose of quick action "generate constructor" make method contructor for assign value to fields or properties. Don't use it in the case of just assigning default values.
do you mean initialize properties? Initializing properties through the code reflection mechanism also requires one-by-one assignments. For private object properties, it is necessary to de-private encapsulation. The operation of initializing properties in c# is generally to initialize object properties or object initializers in the form of constructors. Thank you hope it helps you
class Program
{
static void Main(string[] args)
{
Student student = new Student()
{
age = 25,
name = "java",
sex = "female"
};
}
class Student
{
public int age { get; set; }
public string name { get; set; }
public string sex { get; set; }
public Student()
{
}
public Student(int age, string name,string sex)
{
this.age = age;
this.name = name;
this.sex = sex;
}
}
}

Enforce properties of an object not beeing null

My business logic receives often objects (DTOs) like the following one:
public class CreateUserRequest
{
public string FirstName { get; set; }
public string LastName { get; set; }
public EMailAddress EMail { get; set; }
}
This is simplified and I could use this class to create a new user in my app.
However, many times some of the properties have to be set (!= null), so I need to enforce them like for example like this:
public class CreateUserRequest
{
CreateUserRequest()
{
ThrowIfAnyNotValid();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public EMailAddress EMail { get; set; }
public void ThrowIfAnyNotValid()
{
Ensure.ThrowIfNull(FirstName, nameof(FirstName));
Ensure.ThrowIfNull(LastName, nameof(LastName));
Ensure.ThrowIfNull(EMail, nameof(EMail));
}
}
This works nice, but I am wondering if there is an easier solution.
I know that there is the nullable context feature like described here, but this is not exactly what I want.
If I enable this feature, the compiler will throw warnings and complains that all fields of my class could be null.
The only way to avoid this is to list all of them in the constructor, but this is again much boilerplate code if my classes have many properties.
Actually I need a class where some properties are enforced to be not null by the compiler.
Something like this:
public class CreateUserRequest
{
public stringForcedNotNull FirstName { get; set; }
public stringForcedNotNull LastName { get; set; }
public stringForcedNotNull EMail { get; set; }
}
So this would throw an exception or even a compiler error:
var request = new CreateUserRequest();
And only this would be fine:
var request = new CreateUserRequest()
{
FirstName = "Joe",
LastName = "Schmidt",
EMail = "Joe.Schmidt#foe.de"
}
Is there a way in C# that I missed?
There are many ways you can ensure that there won't be any null values on construction. However there is probably no simple way to enforce not null values automatically during whole lifetime of instance of your classes as it would be way too processing power hungry with little gain. Common appoach would be to check values every time you need them, or only on creation.
You can add mandatory parameters to constructor like this:
public class CreateUserRequest
{
CreateUserRequest(string FirstName, string LastName, EMailAddress EMail)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.EMail = EMail;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public EMailAddress EMail { get; set; }
}
This code won't allow you to call new CreateUserRequest() without parameters and thus create empty values.
Another solution I came up with is to check values dynamically. I made two separated classes so you don't have to put chcek code into each one, you just inherit from BaseClass when creating new clases
public class CreateUserRequest : BaseClass
{
public string FirstName { get; set; }
public string LastName { get; set; }
public EMailAddress EMail { get; set; }
}
public class BaseClass
{
public BaseClass()
{
if (!this.IsValid)
throw new Exception(/*custom message or whatever*/);
}
public bool IsValid
{
get
{
if (this.GetType().GetProperties().Any(p => p.GetValue(this) == null))
return false;
else
return true;
}
}
}
You can also call IsValid property from anywhere which might be handy and you might even move it out of constructor.
Last thing I'd like to mention is default value.
public class CreateUserRequest
{
public string FirstName { get; set; } = "John";
[DefaultValue("Doe")]
public string LastName { get; set; }
[DefaultValue("John.Doe#email.com")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public EMailAddress EMail { get; set; }
}
Note that there are many options to do that.
First is the simplest one.
Second utilizes DefaultValueAttribute which can be handy in combination with other features but practically does the same thing as first one.
Last one is example of using JsonProperties coming from NewtonsoftJson. When you have for example web application and rely on data comming from Ajax requests, this can come really handy.
Another thing reason why this approach is really helpful is because many methods especially from Linq library can work with default values like FirstOrDefalt() which would in your case return null but in my case it would return values stored in DefaultValueAttribute.

How to make a class to have an automatic implicit constructor like in the case of a record type?

Following are examples of record:
Immutable - either of the following syntax:
public record Person(string FirstName, string LastName);
public record Person
{
public string FirstName { get; init; } = default!;
public string LastName { get; init; } = default!;
};
Mutable:
public record Person
{
public string FirstName { get; set; } = default!;
public string LastName { get; set; } = default!;
};
The record type can be instantiated using: Person person = new("Nancy", "Davolio");
Although I have not tried the following line, but I have seen online examples instantiating records like this also: Person person = new Person("Nancy", "Davolio");
So it looks like the record type provides an implicit constructor (that is - I didn't have to define a constructor).
How to make a class to have an automatic implicit constructor like this? Is this possible?
Simple answer: No it's not possible.
You can declare multiple constructors and do what you want in the default one.
public class Person
{
public Person()
{
// Here you can do what you want for default "settings"
}
public Person(string firstname, string lastname) : this()
{
Firstname = firstname;
Lastname = lastname;
}
public string Firstname { get; set; }
public string Lastname { get; set; }
}

private init in C# props?

What does private access modifier for init only setter in C# mean? I usually make setter as private for most of the properties in my domain classes. With init, does it matter?
The following seem to work without any problem, the compiler does not complain.
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
So how is the above different from the below. There is not private below.
public class Point
{
public int X { get; init; }
public int Y { get; init; }
}
It affects where the setter can be called from, just like normal setters.
Consider this code:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
class Program
{
static void Main()
{
var point = new Point { X = 10, Y = 20 };
}
}
That fails with two compile-time errors:
The property or indexer 'Point.X' cannot be used in this context because the set accessor is inaccessible
(and the equivalent for Y).
The same initializer would be valid in the Point class, because the set accessors are accessible there. For example, you might want to use a public factory method, which is implemented with an object initializer:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
public static Point FromXY(int x, int y) =>
new Point { X = x, Y = y };
}
(There are various reasons why that might not be ideal, or you might prefer to add parameters to a private constructor, but it's an example of where the private init-only setters are accessible.)
Likewise the code above would be valid without the private part of the set accessors, because then they can be called from anywhere (as part of an object initializer).
The init keyword was added in c# 9.0 in order to add immutable properties on objects.
The problem we used to have is that if you have this object you could still modify the Name property (although it has a private setter) via a public method. for example:
public class Person
{
public Person(string name)
{
this.Name = name;
}
public void SetName(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
And we also couldn't use object initializers
var person = new Person
{
Name = "Jane Doe" // Compile Error
};
Now, if we change the code to use init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; init; }
}
We are now able to use object initializers
var person = new Person
{
Name = "Jane Doe" // No error
};
But, if we use your private init like your example
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; private init; }
}
We won't be able to use object initializers
var person = new Person
{
Name = "Jane Doe" // Compile error
};

How to create a subclass with restrictions?

Can we create a subclass of a base class, like creating a view of a table in SQL, in C#?
Example of desired behaviour:
public class EmployeeSpecificUsage : Employee
{
public string firstName;
public string field1;
public int age;
public string Name; //Error! Not implemented in main class
}
public abstract class Employee
{
public string firstName;
public string lastname;
public int age;
public string workTitle;
public string field1;
public string field2;
public string field3;
}
Objectives:
Reduce the number of field members visible.
Forbid adding new fields, respecting the original model.
Your understanding of subclassing is incorrect. Subclassing is a way of extending the base class, not taking away from it. Whatever a base class has, all subclasses would have it as well.
This is different from views in SQL, which can both take away columns and also add computed columns.
Although inheritance does not allow you to reduce the number of visible members, you can do it with composition. Wrap Employee in a RestrictedEmployee, and expose only the members that you want others to see:
public class EmployeeSpecificUsage {
private readonly Employee wrapped;
public EmployeeSpecificUsage(Employee e) {
wrapped = e;
}
public string firstName => wrapped.firstName;
public string field1 => wrapped.field1;
// Two fields above use C# 6 syntax. If it is not available,
// use syntax below:
public int age {
get {
return wrapped.age;
}
}
}
As far as prohibiting the addition of new fields goes, you cannot do that with either inheritance or composition: if you are allowed to subclass at all (i.e. the base class is not sealed) you would be able to add new members. Composition is a lot weaker than inheritance, so you could add new fields even to sealed classes by wrapping them.
An interface gives you access to an aspect of a class (as opposed to a derived class that actually extends the base class).
Have a look at this:
public class Employee : IEmployeeSpecificUsage
{
public string firstName { get; }
public string lastname { get; }
public int age { get; }
public string workTitle { get; }
public string field1 { get; }
public string field2 { get; }
public string field3 { get; }
}
public interface IEmployeeSpecificUsage
{
public string firstName { get; }
public string field1 { get; }
public int age { get; }
}
If you reference to an Employee instance by the IEmployeeSpecificUsage interface, you will only "see" what's in the interface.
You cannot add new interfaces without changing the "base class", though, as it has to declare that it implements those interfaces.
Interfaces can be used as views.
public interface IView
{
string FirstName { get; }
int Age { get; }
string Name { get; }
}
public class Employee: IView
{
// make fields private if possible
private string firstName;
private string lastname;
private int age;
private string workTitle;
private string field1;
private string field2;
private string field3;
// implements IView.FirstName as an auto property
public string FirstName { get; set; }
// implements IView.Age: returns the private age field
public int Age { get { return age;} }
// explicit implementation of IView.Name: visible only as IView
string IView.Name { get { return lastName + ", " + firstName; } }
}
And then:
Employee employee1 = new Employee(); // FirstName and Age are visible on employee1
IView employee2 = new Employee(); // Name is visible, too
If you want to provide a readonly access to an inner field of a class check out public Properties with getter. Make you field members protected. In such a way you will have an ability to implement custom logic for Name property composing it from firstname and lastname field.
public class EmployeeSpecificUsage : Employee
{
public string FirstName { get { return firstName; }};
public string FullName { get { return string.Format("{0} {1}", firstName, lastName); }};
}
public class Employee
{
protected string firstName;
protected string lastname;
protected int age;
protected string workTitle;
protected string field1;
protected string field2;
protected string field3;
}
An option would be to create properties in the base class with protected setters and public getters.

Categories