I was reading Jon Skeet's C# in depth and came across the explanation for auto-implemented properties in C# 3.
The code for this was:
class Product
{
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product(string name, decimal price)
{
Name = name;
Price = price;
}
Product() {}
public static List<Product> GetSampleProducts()
{
return new List<Product>
{
new Product { Name="West Side Story", Price = 9.99m },
new Product { Name="Assassins", Price=14.99m },
new Product { Name="Frogs", Price=13.99m },
new Product { Name="Sweeney Todd", Price=10.99m}
};
}
}
And the text that explains this is
Now the properties don’t have any code (or visible variables!) associated with them, and you’re building the hardcoded list in a very different way. With no name and price variables to access, you’re forced to use the properties everywhere in the class, improving consistency. You now have a private parameterless constructor for the sake of the new property-based initialization. (This constructor is called for each item before the properties are set.) In this example, you could’ve removed the public constructor completely, but then no outside code could’ve created other product instances.
I'm unable to wrap my head around the portion marked in bold. It says that the private constructor is there for the auto-implemented properties and is called every time before it is set. However, even when I put a console in there it did not get called. And even with the private constructors removed the code ran fine.
I know the role of private constructors in C# but I am unable to understand how it is related to auto-implemented properties if it is from the text above.
This piece of code is using object initializer syntax in GetSampleProducts static method.
Object initializers can be used only on types with parameterless constructor, because it's all about syntactic sugar.
This
var p = new Product { Name="West Side Story", Price = 9.99m }
is really translated into this under the hood
var p = new Product();
p.Name = "West Side Story";
p.Price = 9.99m;
It means parameterless constructor is required for var p = new Product(); call. And it will be actually called for each item before the properties are set.
Constructor is private, but as far as GetSampleProducts is inside Product type, it can access Product private members. If you try the same syntax outside of this class it will fail.
So, this
You now have a private parameterless constructor for the sake of the new property-based initialization.
Actually means that constructor isn't used for auto-implemented properties here, it's required for property-based initialization (this term means object initializer), and if you remove it, you will get compilation errors.
Instead of using private field in class & then in a property get you return the private field as is:
private int age;
public int Age
{get {return age;}
set {age = value}
}
With auto implantation the private int gets created behind the scenes.
Syntax for auto implemented property:
public int age {get; set;}
Related
I am very new to programming so I was trying to do some work with and got stuck with my problem.
Here is my code:
//Properties
private static readonly List<string> category = new List<string>
{
"Electric",
"Household",
"Garden",
"Miscellaneous"
};
Category HAS to be "readonly"
// Constructor
public Product(List<string> category)
{
// this.category shows error that it cannot be accessed with an instance reference;
// qualify it with a type name instead
this.category = category;
}
Also in the default constructor I cannot pass it
// Default Constructor
public Product() : this("Miscellaneous")
{
}
So, how to pass 1 one of strings within the list? Or should I use arrays for this? And how do I print it out later?
class TestProduct
{
static void Main(string[] args)
{
// Assigning correct properties to the product
Product p1 = new Product(1234567, "Cake", "Miscellaneous", 7.5, 150);
Console.WriteLine(p1);
Console.ReadLine();
}
}
Hope my question is clear.
If you have a fixed set of categories, you can use an enum to store all values.
public enum ProductCategory
{
Electric,
Household,
Garden,
Miscellaneous
}
You can create a default constructor like this:
public enum ProductCategory
{
Electric,
Household,
Garden,
Miscellaneous
}
public class Product
{
public ProductCategory Category { get; }
public Product(ProductCategory category)
{
this.Category = category;
}
public Product() : this(ProductCategory.Miscellaneous)
{
}
}
static void Main()
{
Product p1 = new Product();
Console.WriteLine(p1.Category); // output: Miscellaneous
Console.ReadKey();
}
If you still want to store your category in a string, you can adapt this example. If you want a fixed list of valid categories, you can check if the category is valid in the constructor.
Category HAS to be "readonly"
The problem is not that it is readonly, the reason why you're getting cannot be accessed with an instance reference, qualify it with a type name instead is because you declared the property as static. A static property cannot be accessed as an instance property.
Also in the default constructor I cannot pass it
Yes you can, if you actually pass in the type you declared.
public Product() : this("Miscellaneous") //You're trying to pass in a string
{
}
Can you see why you cannot pass in that string into your base constructor?
public Product(List<string> category) //base constructor takes a List<string>
{
//stuff
}
You could create a base constructor which actually takes a string:
public Product(string cat)
{
//Validate that the category passed in is valid, I.E. in your list
foreach (var item in category)
{
if(object.Equals(item, cat))
break;
if(object.Equals(item, category.Last()))
throw new Exception("D'oh! Invalid category");
}
//do stuff
}
Something like that. There are probably better ways to validate. Or just make your categories an Enum and use something like Enum.TryParse to validate instead.
I assumed you don't actually want it to be a static variable (this question might help), as long as you are receiving it in the constructor. Maybe what you want it is to be immutable, which is something quite different.
You can define that constructor this way.
public class Product
{
private readonly List<string> _categories;
public Product() : this(new List<string>() { "Miscellanous"})
{
}
public Product(List<string> category)
{
_categories = category;
}
}
Or this way
public class Product
{
// other code
public Product()
{
categories = new List<string>();
categories.Add("Miscellanous");
}
}
Also readonly only forbids changing the reference to the _categories variable. If you want the content to be immutable, then you should have a look at other kind of data structures or simply do it in the code.
Remove the this qualifier from this.category because you are accessing a static variable which by definition cannot belong to an instance of a class.
Of course this means you'll get a naming collision because the static category cannot be differentiated from the local category - so fall back to using a naming convention like an underscore at the start of the name for the static variable - _category.
You should also rethink why you made the private variable category static - there is no reason for it to be that way.
[...] that sets the Category to Miscellaneous
To solve your main issue - there is no way to do this without writing a new constructor that takes a single string (because you cannot statically define or enforce the length of a List<>, you can only check that programmatically). A good option is to use enums as suggested by #apk, then throw an ArgumentOutOfRangeException from within the chained constructor if the value Miscellaneous isn't passed in. But you should rethink even that strategy - if the value must be Miscellaneous then consider defaulting to that in the chained constructor, don't allow an arbitrary value to be passed in and then test for the one possible correct value.
For any given class, obviously I would have something like:
public class Stuff {
int field1;
int field2;
// [etc.]
public Stuff (int field1In, int field2In) {
field1 = field1In;
field2 = field2In;
}
}
However, for many fields, indirectly assigning properties from parameters like this seems ugly and indirect. Is there any more direct way? For instance, where instead of specifying a parameter name, you could just specify the fields name, and it would directly assign it?
I'm guessing the reason why you want to initialize fields in the constructor is for immutability reasons, but since you haven't made the fields readonly (and you've called your fields prop), you can obviously also use the property initializer syntactic sugar, if you change your fields to properties, reducing your LOC as follows:
public class Stuff {
public int Prop1 {get; set;}
public int Prop2 {get; set;}
}
Caller would just use the default constructor:
var myStuff = new Stuff() {
Prop1 = 54,
Prop2 = 88
}
Edit
I guess to sum up the below banter:
If 'prop1' et al are to be retained as fields, then there is no shorthand.
If 'prop1' et al need to be kept private (albeit initialized externally) then there is also no shorthand.
If the fields can be converted to publically setable properties, then you can use automatic properties, as per above.
However, and I’m speculating here, if your question is as a requirement of using ctor initializers for the purpose of promoting the immutability of your fields, it would be nice to allow a hybrid syntactic sugar allowing for a combination of immutability similar to autoproperties which will reduce the LOC.
Several folk are already calling for readonly automatic properties to be implemented in C#, although it is speculative as to whether this extend to initializer syntax as part of the constructor.
This might allow the typical verbose pattern of:
class SomeClass
{
private readonly SomeDependency _dep1;
private readonly AnotherDependency _dep2;
. . .
public SomeClass(SomeDependency dep1, AnotherDependency dep2, …)
{
_dep1 = dep1;
_dep2 = dep2;
…
}
To be replaced with simpler, yet equivalent code. I have absolutely no idea what the syntax would look like ... but it would mean a property (or field) is "private readonly" except for the one exception of CTOR initializer syntax ...
"ReadOnly" SomeDependency Dep1 { private get; private set; }
"ReadOnly" SomeDependency Dep1 { private get; private set; }
. . . No need for ctor since can just use the default constructor
And which could then be used at construction time:
var x = new SomeClass
{
Dep1 = ...,
Dep2 = ...
}; // OK, this time only, because it is at construction time.
But not mutated
x.Dep1 = ...; // Compile time err ...
And obviously the requirement would be that ALL such properties must be initialized simultaneously (or just be baked with the type default for the object's lifespan )...
Supposing I have an Album class :
public class Album
{
public string Name {get; set;}
public string Artist {get; set;}
public int Year {get; set;}
public Album()
{ }
public Album(string name, string artist, int year)
{
this.Name = name;
this.Artist = artist;
this.Year = year;
}
}
When I want to assign data to an object of type Album, what is the difference between the next 2 approaches :
Via Constructor
var albumData = new Album("Albumius", "Artistus", 2013);
or when instantiating
var albumData = new Album
{
Name = "Albumius",
Artist = "Artistus",
Year = 2013
};
Both approaches call a constructor, they just call different ones. This code:
var albumData = new Album
{
Name = "Albumius",
Artist = "Artistus",
Year = 2013
};
is syntactic shorthand for this equivalent code:
var albumData = new Album();
albumData.Name = "Albumius";
albumData.Artist = "Artistus";
albumData.Year = 2013;
The two are almost identical after compilation (close enough for nearly all intents and purposes). So if the parameterless constructor wasn't public:
public Album() { }
then you wouldn't be able to use the object initializer at all anyway. So the main question isn't which to use when initializing the object, but which constructor(s) the object exposes in the first place. If the object exposes two constructors (like the one in your example), then one can assume that both ways are equally valid for constructing an object.
Sometimes objects don't expose parameterless constructors because they require certain values for construction. Though in cases like that you can still use the initializer syntax for other values. For example, suppose you have these constructors on your object:
private Album() { }
public Album(string name)
{
this.Name = name;
}
Since the parameterless constructor is private, you can't use that. But you can use the other one and still make use of the initializer syntax:
var albumData = new Album("Albumius")
{
Artist = "Artistus",
Year = 2013
};
The post-compilation result would then be identical to:
var albumData = new Album("Albumius");
albumData.Artist = "Artistus";
albumData.Year = 2013;
Object initializers are cool because they allow you to set up a class inline. The tradeoff is that your class cannot be immutable. Consider:
public class Album
{
// Note that we make the setter 'private'
public string Name { get; private set; }
public string Artist { get; private set; }
public int Year { get; private set; }
public Album(string name, string artist, int year)
{
this.Name = name;
this.Artist = artist;
this.Year = year;
}
}
If the class is defined this way, it means that there isn't really an easy way to modify the contents of the class after it has been constructed. Immutability has benefits. When something is immutable, it is MUCH easier to determine that it's correct. After all, if it can't be modified after construction, then there is no way for it to ever be 'wrong' (once you've determined that it's structure is correct). When you create anonymous classes, such as:
new {
Name = "Some Name",
Artist = "Some Artist",
Year = 1994
};
the compiler will automatically create an immutable class (that is, anonymous classes cannot be modified after construction), because immutability is just that useful. Most C++/Java style guides often encourage making members const(C++) or final (Java) for just this reason. Bigger applications are just much easier to verify when there are fewer moving parts.
That all being said, there are situations when you want to be able quickly modify the structure of your class. Let's say I have a tool that I want to set up:
public void Configure(ConfigurationSetup setup);
and I have a class that has a number of members such as:
class ConfigurationSetup {
public String Name { get; set; }
public String Location { get; set; }
public Int32 Size { get; set; }
public DateTime Time { get; set; }
// ... and some other configuration stuff...
}
Using object initializer syntax is useful when I want to configure some combination of properties, but not neccesarily all of them at once. For example if I just want to configure the Name and Location, I can just do:
ConfigurationSetup setup = new ConfigurationSetup {
Name = "Some Name",
Location = "San Jose"
};
and this allows me to set up some combination without having to define a new constructor for every possibly permutation.
On the whole, I would argue that making your classes immutable will save you a great deal of development time in the long run, but having object initializer syntax makes setting up certain configuration permutations much easier.
Second approach is object initializer in C#
Object initializers let you assign values to any accessible fields or
properties of an object at creation time without having to
explicitly invoke a constructor.
The first approach
var albumData = new Album("Albumius", "Artistus", 2013);
explicitly calls the constructor, whereas in second approach constructor call is implicit. With object initializer you can leave out some properties as well. Like:
var albumData = new Album
{
Name = "Albumius",
};
Object initializer would translate into something like:
var albumData;
var temp = new Album();
temp.Name = "Albumius";
temp.Artist = "Artistus";
temp.Year = 2013;
albumData = temp;
Why it uses a temporary object (in debug mode) is answered here by Jon Skeet.
As far as advantages for both approaches are concerned, IMO, object initializer would be easier to use specially if you don't want to initialize all the fields. As far as performance difference is concerned, I don't think there would any since object initializer calls the parameter less constructor and then assign the properties. Even if there is going to be performance difference it should be negligible.
My understanding is any method which does not modify state of the constaining class is a prime candidate to be made static because it does not touch the instance. An instance would be that containing class's data (fields/properties) so if I had a person class with a property called Name (and just that one property), and I am not modifying that property then my class can be set as static, but of course, but the function could be working with another object. Is this the right thing to look for when checking if a method should be made static?
Static variables are described as global variables, but what is the difference of this to any publicly variable? All the variables are in the server's memory and will be lost in a reboot etc. And then use this variable to hold expensive-to-get data (eg running stored procedures in a loop etc).
Thanks
My understanding is any method which does not modify state of the constaining class is a prime candidate to be made static because it does not touch the instance.
I wouldn't say it's a prime candidate, but rather just a candidate. Personally, I think methods should be made static if the API would suggest that it should be static from a logical, algorithmic standpoint. Technically, any method which doesn't change state can be static, but I don't believe it necessarily should be static.
and I am not modifying that property then my class can be set as static, but of course, but the function could be working with another object.
You can only set your class as static in C# if it has absolutely no instance variables. "Instances" of a static class don't exist (and cannot exist), nor can non-static members.
Now - for what I think you're really after...
The difference between a static variable and a non-static variable has to do with how it's accessed. When you define a static field on a class, you're defining a field that will always have a single instance (instance of the field) tied to the class itself. When you define a non-static, normal field, on the other hand, you will potentially have many instances of your field, each residing within one instance of your class.
This is why static variables are often described as global - anything that has access to the class has access to it's one copy of the static variable (provided its publicly accessible). However, non-static fields are different - you need to have a reference to the specific instance of the class in order to read or write to a non-static member.
.
My understanding is any method which
does not modify state of the
constaining [sic] class is a prime candidate
to be made static because it does not
touch the instance.
I don't think this is the right way to think of static vs. non-static. Rather, any method which is not related to the state of a class instance can be static. A name is obviously associated with a particular person, so a Name field on a Person class should almost certainly not be static. Otherwise, you could end up with a scenario like this:
public class Person {
public static string Name { get; set; }
public Person(string name) { Name = name; }
public override string ToString() {
return Name;
}
}
Person dan = new Person("Dan";
Person john = new Person("John";
// outputs "John"
Console.WriteLine(john);
// outputs "John" again, since Dan doesn't have a name property all his own
// (and neither does John, for that matter)
Console.WriteLine(dan);
EDIT: Now, suppose we have a property such as House which can belong to not one but several people. blade asks: "How would this be modeled in code - static?"
My answer: NO, for the same reason already mentioned above. Suppose I've fixed the problem above by making the Name property non-static. Then I introduce a new static House property. Now I have a situation like this:
public class Person {
public string Name { get; set; }
public static House House { get; set; }
public Person(string name, House house) {
Name = name;
House = house;
}
public override string ToString() {
return String.Concat(Name, ", ", House);
}
}
public class House {
public double SquareFootage { get; set; }
public House(double sqft) { SquareFootage = sqft; }
public override string ToString() {
return String.Format("House - {0} sq. ft.", SquareFootage);
}
}
House danAndKatsHouse = new House(1000.0);
House johnsHouse = new House(2000.0);
Person dan = new Person("Dan", danAndKatsHouse);
// outputs "Dan, House - 1000 sq. ft." as expected
Console.WriteLine(dan);
Person kat = new Person("Kat", danAndKatsHouse);
// outputs "Kat, House - 1000 sq. ft.", again as expected
Console.WriteLine(kat);
Person john = new Person("John", johnsHouse);
// outputs "John, House - 2000 sq. ft.", so far so good...
Console.WriteLine(john);
// but what's this? suddenly dan and kat's house has changed?
// outputs "Dan, House - 2000 sq. ft."
Console.WriteLine(dan);
There's a difference between multiple objects of one class sharing the same object and ALL objects of that class sharing the same object. In the latter case, a static property makes sense; otherwise, it does not.
There are a few ways off the top of my head to deal with this scenario. They are:
1. Make the House property non-static
It might seem strange, but you can always just make the House property non-static and you won't ever have to worry about the problem above. Furthermore, assuming you actually do assign the same House object to each Person who shares it, making a change to the House through one Person object will actually achieve the desired effect:
House danAndKatsHouse = new House(1000.0);
// (after making Person.House property non-static)
Person dan = new Person("Dan", danAndKatsHouse);
Person kat = new Person("Kat", danAndKatsHouse);
dan.House.SquareFootage = 1500.0;
// outputs "1500"
Console.WriteLine(kat.House.SquareFootage);
This could actually be a problem, however, if you accidentally assign the same House to two people with the intention of them actually having two different Houses:
House smallerHouse = new House(1000.0);
House biggerHouse = new House(2000.0);
Person dan = new Person("Dan", smallerHouse);
Person john = new Person("John", biggerHouse);
Person bill = new Person("Bill", smallerHouse);
bill.House.SquareFootage = 1250.0;
// yikes, Dan's house just changed...
Console.WriteLine(dan);
2. Use a database
The fact is that the notion of making a house a property of a person is somewhat a forced concept to begin with. A person may move out of their house, different people may move in, etc. Really a relationship exists between the two, which makes using a database an appropriate solution.
Using this approach, what you'd do is have a Persons table, a Houses table, and a third table (maybe PersonHouses) containing id pairs from the other two tables to represent, I guess, home ownership.
If you don't have a full-blown database at your disposal, you can achieve effectively the same result (in .NET) using a System.Data.DataSet and its collection of System.Data.DataTable objects in your code. However, in any scenario where you are translating rows of a database (or DataTable) to objects and then back again, you do need to be aware of impedence mismatch. Basically, whatever meticulous precautions you take in your code to encapsulate your data are out the window once that data is in the database, ready to be modified by anyone with sufficient permissions.
3. Use dictionaries
Another approach, similar to using a database but a bit more work (and I think some programmers who've gone the DataSet route shudder at the thought of this), is to use dictionaries to keep track of your Person and House objects. The quickest way to implement this approach would be to have a Dictionary<int, Person> and a Dictionary<int, House>, and assign each Person a HouseId property:
public class Person {
public int Id { get; private set; }
public string Name { get; set; }
public int HouseId { get; set; }
private static int LastIdValue { get; set; }
private static Dictionary<int, Person> People { get; set; }
static Person() {
LastIdValue = 0;
People = new Dictionary<int, Person>();
}
// make the constructor private to disallow direct instantiation
private Person(int id, string name, int houseId) {
Id = id;
Name = name;
HouseId = houseId;
}
// only permit construction through this function, which inserts
// the new Person into the static dictionary before returning it
static public Person NewPerson(string name, int houseId) {
Person p = new Person(LastIdValue++, name, houseId);
People.Add(p.Id, p);
return p;
}
static public Person getPersonById(int id) {
Person p = null;
return People.TryGetValue(id, out p) ? p : null;
}
}
public class House {
public int Id { get; private set; }
public int SquareFootage { get; set; }
private static int LastIdValue { get; set; }
private static Dictionary<int, House> Houses { get; set; }
static House() {
LastIdValue = 0;
Houses = new Dictionary<int, House>();
}
// make the constructor private to disallow direct instantiation
private House(int id, int sqft) {
Id = id;
SquareFootage = sqft;
}
// only permit construction through this function, which inserts
// the new House into the static dictionary before returning it
static public House NewHouse(int sqft) {
House h = new House(LastIdValue++, sqft);
Houses.Add(h.Id, h);
return h;
}
static public House getHouseById(int id) {
House h = null;
return Houses.TryGetValue(id, out h) ? h : null;
}
}
House firstHouse = House.NewHouse(1000.0);
House secondHouse = House.NewHouse(2000.0);
Person dan = Person.NewPerson("Dan", firstHouse.Id);
Person kat = Person.NewPerson("Kat", firstHouse.Id);
Person john = Person.NewPerson("John", secondHouse.Id);
House dansHouse = House.getHouseById(dan.HouseId);
House katsHouse = House.getHouseById(kat.HouseId);
// this prints
if (katsHouse == dansHouse) { Console.WriteLine("Dan and Kat live in the same house."); }
// this also prints
if (dansHouse == firstHouse) { Console.WriteLine("Dan and Kat live in the first house."); }
// this does not print
if (dansHouse == secondHouse) { Console.WriteLine("Dan and Kat live in the second house."); }
This way, all your data encapsulation still holds. However, if you ever need your data to persist between instances of your code running, then you need to serialize your dictionaries in some file format (most likely XML), which could then be edited by anyone with sufficient privileges, and then you're back to the impedence mismatch problem of using a database all over again.
In light of the advantages and disadvantages of each approach, I think what actually makes the most sense -- and makes your life easiest -- is to simply make House a non-static property. This is assuming you don't have tons and tons of Person and House objects to keep track of.
" if I had a person class with a
property called Name (and just that
one property), and I am not modifying
that property then my class can be set
as static"
That is not correct. A person class is almost certainly a domain entity. It is conceivable you might want to have a static method on a Person entity, but I haven't ever come across one. In your example, you would have a private setter for your 'Name' property.
The static-ness of anything should model your domain, rather than being a language implementaion detail.
There are no true globl variables in C#, in the sense that that term is used in other languages like C. The difference between a static object and a global object is that a static object has permissions that are relative to the class in which it is defined. This is a very good thing, because you can create private static members that are only accessible to member of one class. The big problem with the abuse of global variables is the many depenencies to a single global variable that can evolve across a large colleciton of modules. Private static object avoid this problem.
One big problem with static objects is that they are not thread safe. In order to declare a thread safe static object, you must use the ThreadStatic attribute and provide a way for the object to be initialized on first access. You should do this for all multi-threaded environents e.g. ASP.NET, and any general purpose library that might run in multi-threaded environment. Heck, just always do this and you won't be sorry!
If you have a Person class with a static field name:
public class Person {
public static string Name { get; set; }
}
then you can only ever have one name. You can not have a list of persons with different names. Static can be seen as "Unique" in the way that it's value is global. This can be a trap in ASP.net applications by the way, because static applies through the entire application, which means to all users.
Static variables are rather rare and used for data that is really not part of a specific instance of the class. Or to return specific instances.
For example, Guid.Empty is a static field that returns a Guid that has all Bits set to 0.
A good example is System.Drawing.Color. Color has instance-specific variables, for example R,G,B and Alpha, but you have static fields like Color.Black which returns a Black color.
I was wondering what people thought of using properties as object initializers in C#. For some reason it seems to break the fundamentals of what constructors are used for.
An example...
public class Person
{
string firstName;
string lastName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName= value; }
}
}
Then doing object intialization with.....
Person p = new Person{ FirstName = "Joe", LastName = "Smith" };
Person p = new Person{ FirstName = "Joe" };
What you see here is some syntatic sugar provided by the compiler. Under the hood what it really does is something like:
Person p = new Person( FirstName = "Joe", LastName = "Smith" );
Person _p$1 = new Person();
_p$1.FirstName = "Joe";
_p$1.LastName = "Smith";
Person p = _p$1;
So IMHO you are not really breaking any constructor fundamentals but using a nice language artifact in order to ease readability and maintainability.
Object initializers does in no way replace constructors. The constructor defines the contract that you have to adhere to in order to create a instance of a class.
The main motivation for object initializers in the C# language is to support Anonymous Types.
var v = new { Foo = 1, Bar = "Hi" };
Console.WriteLine(v.Bar);
IMHO its sweet. Most objects are newed up with the default constructor, and must have some properties set before they are ready to run; so the object initializers make it easier to code against most objects out there.
Constructors should only really have arguments that are required to construct the object. Object initialisers are just a convenient way to assign values to properties. I use object initialisers whenever I can as I think it's a tidier syntax.
Since you're already using the new C# syntax, might as well use automatic properties as well, just to sweeten up your code a drop more:
instead of this:
string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
use this:
public string FirstName { get; set; }
I think overall it is useful, especially when used with automatic properties.
It can be confusing when properties are doing more than get/set.
Hopefully this will lead to more methods, and reduce the abuse of properties.
Not your original question, but still...
Your class declaration can be written as:
public class Person
{
public string FirstName { get; set; }
public string LastName {get; set; }
}
and if it were my code, I'd probably have an object for Name with fields First and Last.
It's also quite necessary for projected classes returned from a language integrated query (linq)
var qry = from something in listofsomething
select new {
Firstname = something.FirstName,
Lastname = something.Surname
}
Adding to Nescio's thoughts - I'd suggest in code reviews actively hunting down expensive transparent operations in property accessors e.g. DB round tripping.
Object Initializers help to reduce coding complexity in that you don't need to create a half dozen different constructors in order to provide initial values for properties. Anything that reduces redundant code is a positive, in my book.
I believe the primary reason the feature was added to the language is to support anonymous types for LINQ.
If you want to enforce the use of a constructor, you could set your object's default parameterless constructor to private, and leave public only some enforced constructors:
public class SomeObject
{
private SomeObject()
{}
public SomeObject(string someString) //enforced constructor
{}
public string MyProperty { get; set; }
}
Using the above definition, this throws an error:
var myObject = new SomeObject { MyProperty = "foo" } //no method accepts zero arguments for constructor
Of course this can't be done for all cases. Serialization, for example, requires that you have a non-private default constructor.
I for one am not happy with them. I don't think they have a place in the constructor, or MS should got back and refactor them to allow you to use them in a private fasion. If I construct an object I want to pass in some PRIVATE data. I want it set from the outside world once and that's it. With Object Initializers you allow the values passed into the constructor to be modifiable.
Maybe in the future they will change this.