C
C#6mo ago
tama

Best practice for class constructors?

Hello there. I'm creating a class with one private and one public variable. I am a little unsure how the constructor should work when this is the case. As an example:
C#
public class A
{
private readonly typeX _var1;
public typeY var2Something { get; set; }

public A(typeX var1, typeY var2)
{
_var1 = var1;
var2Something = var2;
}
}
C#
public class A
{
private readonly typeX _var1;
public typeY var2Something { get; set; }

public A(typeX var1, typeY var2)
{
_var1 = var1;
var2Something = var2;
}
}
Does it make sense to declare them first, and then assign them in the initializor? Also, are you supposed to add { get; set; } to the class variable when it's also part of the constructor? I am also unsure what the best practice is for variable names in C#. Some places I have seen names with capital first letter, other times I see something like exampleVariable. I come from Python, where we use _variable_name for private variables, do you also use the underscore in C#?
4 Replies
Joschi
Joschi6mo ago
Let's go through this step by step and clear up some terminology first. Your first class member _var1 is something called a field. Those are typically private and their names often start with the underscore _fieldName. Your second membter var2Something is called a Property. Those are named like this PropertyName. The {get; set;} which denotes your property are a shortcut called auto property. It denotates how someone can access this property. In your example anyone with a reference to this object can read and write to var2Something. You can also add access modifiers in them, like {get; private set;}. Now anyone could read, but only code inside the class can write. Constructors are expected to not do any heavy work and leave the object in an valid state. For example all non nullable properties and fields should be populated. If let's say var2Something is expected to be null sometimes, you would not need to put it in the constructor. But if it is needed for the functionality of your calls and should not be null ever, you need to ensure that it is populated at all time. One way is the constructor, another would be to declare it required, which enforces the callee to provide a value at initialization. $getsetdevolve
MODiX
MODiX6mo ago
class Foo
{
private int _bar;

public int GetBar()
{
return _bar;
}

public void SetBar(int bar)
{
_bar = bar;
}
}
class Foo
{
private int _bar;

public int GetBar()
{
return _bar;
}

public void SetBar(int bar)
{
_bar = bar;
}
}
can be shortened to
class Foo
{
private int _bar;

public int GetBar() => _bar;

public void SetBar(int bar) => _bar = bar;
}
class Foo
{
private int _bar;

public int GetBar() => _bar;

public void SetBar(int bar) => _bar = bar;
}
can be shortened to
class Foo
{
private int _bar;
public int Bar {
get { return _bar; }
set { _bar = value; }
}
}
class Foo
{
private int _bar;
public int Bar {
get { return _bar; }
set { _bar = value; }
}
}
can be shortened to
class Foo
{
private int _bar;
public int Bar {
get => _bar;
set => _bar = value;
}
}
class Foo
{
private int _bar;
public int Bar {
get => _bar;
set => _bar = value;
}
}
can be shortened to
class Foo
{
public int Bar { get; set; }
}
class Foo
{
public int Bar { get; set; }
}
tama
tamaOP6mo ago
So, I'm still a little unsure if my example is the correct way to add the public variable. If all variables are public, it's usually enough to declare them and not create an explicit constructor. What about this case? Is it enough to declare the public variable, and then only include the private variable in the constructor?
Joschi
Joschi6mo ago
Ok let's use a person as an example class.
class Person
{
public string Name { get; set; }
public string LastName { get; set; }
}
class Person
{
public string Name { get; set; }
public string LastName { get; set; }
}
If I use this class and initialize int var myPerson = new Person(). The Name and LastName properties will be null. Which is probably not what you actually want to happen. In fact the compile will even warn me, that those two non nullable properties could be null. Sur you could trust your consumer to fill in the name and last name after creating the object.
var myPerson = new Person();
myPerson.Name = "Tama";
myPerson.LastName = "Gotchi";
Console.WriteLine(myPerson.Name);
var myPerson = new Person();
myPerson.Name = "Tama";
myPerson.LastName = "Gotchi";
Console.WriteLine(myPerson.Name);
but it would be way better to enforce the consumer to fill those properties right? Wether or not something is filled in your constructor does not depend on it's visibility, but on the question "does this need to be assigned at all times".
Want results from more Discord servers?
Add your server