0

Program.cs

Book book1 = new Book("Lord Of the Rings", "Fantasy");
book1.bookName = "Harry Potter"; // Updating with constructor
book1.BookName = "Witcher"; // Updating with Property

Books.cs

public string bookName;
public string genre;


public Book() {}

public string BookName {get; set;} 

I understand that constructor is used to initialize an object. However I would like to know why it is better to set value as property than use a constructor?

  • 3
    Sometimes you want to be able to modify an object after construction. Sometimes you want to only be able to specify values *at* construction. Sometimes you want to be able to do both. It's not that any one of those is "better" than the other in a universal way - although immutability can definitely be easier to reason about. – Jon Skeet Dec 11 '19 at 11:17
  • I'm not sure what is the question. Are you asking about difference between public property vs public member field? https://stackoverflow.com/questions/1180860/public-fields-versus-automatic-properties – orhtej2 Dec 11 '19 at 11:17
  • If a property is read only for an object instance than it makes sense to initialize it via the constructor and then provide a read only property accessor - i would have though in this case it makes sense do set the name of the name via the constructor ? – auburg Dec 11 '19 at 11:18
  • who sais it **is** better? Pretty opinion-based, IMHO. Having said this there are far too many reasons for one over the other, that all depend on your context and what you want to achieve. – MakePeaceGreatAgain Dec 11 '19 at 11:19
  • By the way you can also set a property within your constructor. It´s no either this or that. – MakePeaceGreatAgain Dec 11 '19 at 11:27

1 Answers1

2

Setting with constructor is OK, moreover it can make the class immutable (and thus, thread safe):

public class Book {
  public Book(string bookName) {
    //TODO: Put more validation here if required 
    BookName = bookName != null 
      ? bookName 
      : throw new ArgumentNullException(nameof(bookName));
  }

  // Once set in the constructor, this property won't be changed
  public string BookName {get;}  

  public override string ToString() => BookName; 
}

If you let BookName be changed after construction then property with set is quite OK:

public class Book {
  // Please, note private - m_BookName field is a hidden implementation detail
  private string m_BookName = "???"; 

  public Book() {
  }

  public string BookName {
    get {
      return m_BookName;
    }
    set {
      if (null == value)
        throw new ArgumentNullException(nameof(value)); 

      //TODO: Put more validation here if required

      m_BookName = value; 
    } 
  }  

  public override string ToString() => BookName; 
}

What's not OK is to expose a public field:

public class Book {
  //TODO: don't put it like this!
  public string bookName;
  ...
}

For instance:

Book myBook = new Book();
...
// bookName field is exposed, anyone can write anything into it
myBook.bookName = null;    

...

// Harmless check, isn't it?
if (myBook.bookName.Contains("tale")) { // <- Exception thrown
  ...
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • @HimBromBeere: technically, yes, but "does not contain any logic" often means "we didn't want any logic to put in version 1.0". Validation(s), events (on property changing/changed), inner logics tend to appear, that's why property is a safier choice. – Dmitry Bychenko Dec 11 '19 at 11:32