Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I was reading about constructor chaining and I was wondering, if one has a sub instance object inside a class, take for example below, the Course class, how should it be instantiated with the professor object?
public Course(string courseCode, string courseTitle, Professor teacher)
{
if(String.IsNullOrWhiteSpace(courseCode))
{
throw new ArgumentNullException("Course Code Cannot Be Empty");
}
this.courseCode = courseCode;
if(String.IsNullOrWhiteSpace(courseTitle))
{
throw new ArgumentNullException("Course Title Cannot Be Empty");
}
this.courseTitle = courseTitle;
this.prof = Professor.Clone(teacher);
}
public Course(string courseCode, string courseTitle)
:this(courseCode,courseTitle,new Professor())
{
}
Professor class:
public int id {get; private set; }
public string firstName{get; private set;}
public string lastName {get; private set;}
public Professor(int ID, string firstName, string lastname)
{
this.id = ID;
if(String.IsNullOrWhiteSpace(firstName))
{
throw new ArgumentNullException("first name Cannot be Null");
}
this.firstName = firstName;
if(String.IsNullOrWhiteSpace(lastname))
{
throw new ArgumentNullException("last name cannot be null");
}
this.lastName = lastname;
}
The comment in the linked question suggested this:
I think that the best practice when chaining constructors is to call
the constructor with more arguments from the one with less arguments,
providing default values.
My Course class has a professor object as one of the arguments. What should my default values for professor be if the user were to create a course that doesn't have a professor?
public Course(string courseCode, string courseTitle)
:this(courseCode,courseTitle,new Professor())
{
}
in this you shouldnot instantiate new professor() as you dont have any professor.
public Course(string courseCode, string courseTitle)
:this(courseCode,courseTitle,null)
{
}
use this constructor when you want to create course with no professor and assign the professor object only if it is not null in the other constructor.
If a Professor cannot exist without a name or ID, then I would simply not have an overloaded constructor in Course that creates a default professor. You would manage a Course instance with a null Professor as needed.
If they can, and you want a generic professor "John Smith" then I would let the Professor class specify what an "empty" professor means (although I would not recommend this):
public class Professor
{
...
private static Professor _default;
public static Professor Default
{
get
{
if (_default == null)
_default = new Professor(-1, "John", "Smith");
return _default;
}
}
}
And then change your overloaded constructor in Course to:
public Course (string courseCode, string courseTitle)
: this(courseCode, courseTitle, Professor.Default)
This separate of duties will keep your code a little more maintainable, and the singleton instance of a default professor will allow you to do things later like:
if (myProfInstance == Professor.Default)
// insert into DB, for example
What should my default values for professor be if the user were to create a course that doesn't have a professor?
The design approach should provided that answer to what a default professor is when one cannot be directly associated. Otherwise as a developer you need to create that default professor which is simply a bare minimum informational instance which can be handled and updated in future processing in the system.
The idea behind constructor chaining is to simply to organize overloaded constructors to centralize common instantiation actions so they are not repeated.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Consider a simple class
public class MyClass
{
private int myProperty
...
public int MyProperty
{
get
{
return myProperty;
}
set
{
// some evaluation/condition
myProperty= value;
}
}
...
}
Now, if I want to create an empty constructor where I set default values for the class properties I could do this either this way:
public MyClass()
{
myProperty = 1;
...
}
or this way:
public MyClass()
{
MyProperty = 1;
...
}
Both examples seem valid, since I would never set a default value, that doesn't meet the requirements in the setter evaluation.
The question is, is there a best practice or doesn't it matter anyway?
What would be the advantage of one or the other be (as I can't find any)? Is there some reference, where this question is adressed?
So far I have come across code from many different developers that use either or both ways...
You can use both. But i prefer the first one. Why? Because the value that the property uses is directly assigned. For C# 6 above, you can use default value in a property directly without using constructor.
public class Person
{
public string FirstName { get; set; } = "<first_name>";
public string LastName { get; set; } = "<last_name">;
}
I personally like to set it as you done in first block.
For me it serve as additional fact of method is constructing object, not using alredy constructed. Also it makes me sure that properties is not called (they transform to set/get functions which results in couple of excess instruction).
But i believe that both variants are valid and maybe compiler optimizes properties to direct assignment.
For simple data first method is ok. But on more complex data, you could have a condition in the set (depending to another variable for example, set { if (Config.TestEnv) ...} so if you directly set the private value, you could be in trouble.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
When to use Methods and Properties in C#?
They can do same thing but when to use both of them.
And also is it possible to set a whole object via C# Property instead of single value.?
A property is more or less what we use to describe different things about a class. They let us define what a class can do and essentially what that class is all about. Consider the following:
namespace Example
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime Birthday { get; set; }
}
}
Name, Age, and Birthday would be considered properties of the Person class. They define what a person is and give us a way to give the class value. A method would then be used to do various things with the properties. You could write a method to get or set the value of a property such as:
public string GetName()
{
return Name;
}
public void SetName(string name)
{
Name = name;
}
However these would be pointless considering the Name property is public meaning it can be accessed whenever we create an instance of the Person class. The above methods would be used if we wanted to set the Name property, but keep it private. Another example of a method would be if we wanted a way to say create a new instance of the person class. By default visual studio will let you instantiate a new Person object like so:
Person jim = new Person();
However we can also write our own "constructor" method to allow us to create a new Person and set it's properties at the same time.
public Person(string name, int age, DateTime birthday)
{
Name = name;
Age = age;
Birthday = birthday;
}
Now we have an easy, streamlined way to instantiate a new Person object which uses a constructor method, and we can create a new Person object like so:
Person jim = new Person("Jim", 25, DateTime.Today);
But the use of methods dont stop there. Since DateTime is the way we represent the Birthday property, we could write a method that could convert a string into the appropriate DateTime.
public DateTime ConvertToDateTime(string date)
{
DateTime temp;
DateTime.TryParse(date, out temp);
return temp
}
Now we can change our constructor to look like this:
public Person(string name, int age, string birthday)
{
Name = name;
Age = age;
Birthday = ConvertToDateTime(birthday);
}
And can instantiate a new Person object like this:
Person jim = new Person("Jim", 25, "1/10/1995");
On a final note, as #vivek nuna said, find a good book! A great one that I've used in previous C# classes would be Murach's book on C#. Also MSDN.com has all the documentation you would need to learn how to code in C#. Try this link to learn more about properties or this link to learn more about methods. Finally, an excellent tutorial I found to learn C# is Scott Lilly's Guide to C#. Not only will you learn the ins and outs of C#, you will get to build a pretty neat and simple text-based RPG!
An proppertie is just a short hand and will create at the background an public get method and a public set
method and a private field to store the value.
// example propertie
public string Name { get; set; }
// at run time it is the same as:
private string Name;
public string GetName(){
return this.Name;
}
public string SetName(string name){
this.Name = name;
}
See Image : the sample class only has an proppertie in code but if you use Reflection to get all the members off the Sample class you will see that at run time these methods are generated but not visable in code.
set_name()
get_name()
'notice the private field Name is not shown because it is private and not visable for the outside, but is genrated.'
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Does a property need to be explicitly initialized like so:
public DeviceSettings ds{ get; private set; } = new DeviceSettings();
Or is it OK to keep it this way?
public class MyDevice
{
public MyDevice(string serial, int patientid)
{
}
public DeviceSettings ds{ get; private set; } //no initialization needed?
}
In your first example ds is set to a new instance of DeviceSettings, in your 2nd example ds is set to default(DeviceSettings) which if that type is a class will be null.
If you wish to do it the 2nd way and your type is a class you will need to add the assignment in the constructor
public class MyDevice
{
public MyDevice(string serial, int patientid)
{
ds = new DeviceSettings();
}
public DeviceSettings ds{ get; private set; }
}
Properties don't need to be initialized at the time you create a new instance of your class. That depends mostly of your business logic.
Property Initializers can help you when you want to initialize your property with a default value,eg:
private DateTime CreateOn { get; } = DateTime.UtcNow;
Which is translated to something like this:
private readonly createOn= DateTime.UtcNow;
public DateTime CreateOn
{
get
{
return createOn;
}
}
That is a property that is going to remain immutable after its initialization.
As #ScottChamberlain pointed out in his answer, you can initialize an auto-implemented property in the constructor of your class. That is a good place to initialize your property if this depends of an external value that is passed as parameter to the constructor, eg:
public class Product
{
private PriceCalculator Calculator {get;set;}
public decimal Price{get {return Calculator.GetPrice();}}
public Product(int factor)
{
Calculator=new PriceCalculator(factor);
}
}
public DeviceSettings ds{ get; private set; } = new DeviceSettings();
That syntax was introduced only in C# 6.0. So it's completely fine do not initialize it. In that case, it will get default value (depends on DeviceSettings, is it value or reference type)
No initialization are needed for instantiate your class.
If you're going to use property, you need to initialize it to have a correct value (it will mainly be null, because null is default value in many cases, except if your redefine it or use a struct). You can do it with C#6 syntaxic sugar as your first example, or in constructor.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I was thinking about language constructs and how when we talk about classes and objects in Object oriented languages we draw comparisons to real world. Like when people talk of Inheritance people would quote an example of Parent and Children. One thing that i don't find in OO languages that i know , mainly C, C++, C#, is that they don't have a mechanism to declare a property as mandatory. What i mean by that is I cannot define a class called human and say that face, hands and lets say eye are mandatory property of my class. By having that construct i can enforce that anyone who is using my class need to set those properties before using my class. If user forgets to set those properties then i should get an compile time error.
Just wanted to see community thoughts on that.
Here is reason why i had asked above question:
When i build my user controls, i want to make sure that users should set some of the properties in their code when they use my control. For example, lets say i build a customer user control that would be used by other developers in my team. Some of the properties that i have exposed are: "CustomerId", "FirstName", "LastName", "Address1", "City", "State" and ZipCode. Now i want to make sure that any consumer of my control should set "CustomerId". Using Constructor to enforce that the value is set is a way but it will throw a run time exception plus how would user call that constructor from .cs file without dynamically creating the control and adding it to control collection.
You can do that, with a DDD principle: create a class with a private default constructor, and a public constructor that accept required parameters and validate its values. If a value is invalid, throw an exception so that the object cannot be created. Properties could also have private setters instead of public setters.
You can also create a 'Mandatory' attribute and put those on top of the properties that are mandatory; and have a mechanism that checks this based on whether a property has been decorated with the attribute or not.
Example:
public class BlogEntry
{
private BlogEntry() {}
public BlogEntry(string title, string body)
{
LastModifiedDate = DateTime.Now;
Title = title;
Body = body;
var blogEntryValidator = new BlogEntryValidator();
blogEntryValidator.ValidateAndThrow(this);
}
public int Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public DateTime? LastPublishDate { get; private set; }
public DateTime LastModifiedDate { get; private set; }
public virtual ICollection<Comment> Comments { get; private set; }
public void Publish()
{
LastPublishDate = DateTime.Now;
}
public void Unpublish()
{
LastPublishDate = null;
}
public void Modify(string title, string body)
{
Title = title;
Body = body;
LastModifiedDate = DateTime.Now;
}
public Comment AddComment(string commentText, string emailAddress, string name)
{
var comment = new Comment(this, commentText, emailAddress, name);
if (Comments == null) Comments = new List<Comment>();
Comments.Add(comment);
return comment;
}
public void RemoveComment(Comment comment)
{
Comments.Remove(comment);
}
}
public class Comment
{
private Comment() {}
public Comment(BlogEntry blogEntry, string name, string emailAddress, string commentText)
{
BlogEntry = blogEntry;
Name = name;
EmailAddress = emailAddress;
CommentText = commentText;
DateWritten = DateTime.Now;
var commentValidator = new CommentValidator();
commentValidator.ValidateAndThrow(this);
}
public int Id { get; private set; }
public string Name { get; private set; }
public string EmailAddress { get; private set; }
public string CommentText { get; private set; }
public DateTime DateWritten { get; private set; }
public BlogEntry BlogEntry { get; private set; }
}
Yes, C++ and C# allow for this via constructors.
class A
{
public:
A(int x, int y, int z)
: _x(x_, _y(y), _z(z) {}
private:
int _x;
int _y;
int _z;
};
You cannot create an instance of A without providing values for _x, _y, and _z.
The reason is that state needed to fulfil class invariants should be provided during object construction, so you should provide values of 'mandatory' properties as constructor parameters. Your question is based on false assumption that an object is characterized by setting state with properties. This is wrong for a handful of reasons, some of which are:
many, if not most OO languages have no properties: Java, C++,...
what you use is only formally an object, it is actually a plain record and it is not very object oriented, same as e.g. C++ struct without methods (see notes at the bottom about setters vs methods)
Allowing the client to create instances of the objects which are only later set up with correct values for mandatory state is sure-fire way to spend many hours in company of debugger.
Let's take some User with invariant that first and last name must always be set.
class User {
public User(string first, string last) { ... }
public User(string first, string last, uint age) : this(first, last) { ... }
}
// client code:
var user = new User("john", "doe");
var user2 = new User("Clint", "Eastwood", 82);
Compiler ensures that no one can instantiate the object without fulfilling the invariants.
Now compare it with your approach:
class User {
public User(string first, string last) { ... }
public User(uint age) { ... }
[Mandatory] public string FirstName { get; set; }
[Mandatory] public string LastName { get; set; }
}
// client code:
var actor = new User(82); // << invalid
actor.FirstName = "Clint";
actor.LastName = "Eastwood"; // << valid
This approach results in more code and allows for a period of time (between << invalid and << valid) where your object is not in a valid state. What if some of property setters throw an exception? You are left with broken object instance floating around. Do you expect the compiler to also verify that code in the setter can not throw? Do you think it is even possible? Besides that, every client which instantiates User instances must check what are the mandatory properties and make sure to set all of them. This effectively breaks encapsulation.
IMO, property setters should be rare, unlike getters. I believe that in such a class you should not have setters for FirstName/LastName, only getters. Instead there should be a method SetName(string first, string last) if you really want to allow name changing. Here's why:
// lets rename actor
actor.FirstName = "John";
actor.LastName = "Wayne";
If the last line throws, you are left with John Eastwood, an actor I have never heard about. With actor.SetName("John", "Wayne") this can't happen.
Additionally, what about property which have dependency in order you specify them, e.g.
obj.ErrorCode = 123; // imagine that error code must be != 0
obj.ErrorMsg = "foo"; // in order to be allowed to set error code
Would you also introduce attributes for that instead of having obj.SetErrorInfo(123, "foo")? This makes it obvious that properties break encapsulation as the order is caused by the implementation detail, unlike with method call.
Quite often, in languages like C#, required state or dependencies is provided in constructor while optional state can be set through properties. However, it is not properties or inheritance which make a language object-oriented.
Sure you can! Just use parameters in constructor to denote which are mandatory.
public class Human
{
public Face Face { get; set; }
public Hand Hand { get; set; }
public Human(Face face, Hand hand) {} etc...
}
In this instance, you cannot use the private constructor, so these properties are essentially "mandatory" in order to use the Human class.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When do you use the “this” keyword?
Can anyone explain me the "this" reference? when we use this ? with a simple example.
When you use this inside a class, you're refering to the current instance: to the instance of that class.
public class Person {
private string firstName;
private string lastName;
public Person(string firstName, string lastName) {
//How could you set the first name passed in the constructor to the local variable if both have the same?
this.firstName = firstName;
this.lastName = lastName;
}
//...
}
In the above example, this.firstName is refering to the field firstName of the current instance of the class Person, and firstName (the right part of the assignment) refers to the variable defined in the scope of the constructor.
So when you do:
Person me = new Person("Oscar", "Mederos")
this refers to the instance Person instance me.
Edit:
As this refers to the class instance, cannot be used inside static classes.
this is used (too) to define indexers in your classes, like in arrays: a[0], a["John"],...
this is a scope identifier. It is used within an object's instance methods to identify behaviors and states that belong to an instance of the class.
Nowadays-fashionable Fluent APIs use this extensively. Basically it's used to get hold of a reference to the current instance.
here's a simple example
public class AnObject
{
public Guid Id { get; private set;}
public DateTime Created {get; private set; }
public AnObject()
{
Created = DateTime.Now;
Id = Guid.NewGuid();
}
public void PrintToConsole()
{
Console.WriteLine("I am an object with id {0} and I was created at {1}", this.Id, this.Created); //note that the the 'this' keyword is redundant
}
}
public Main(string[] args)
{
var obj = new AnObject();
obj.PrintToConsole();
}