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 )...
Related
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;}
I find myself creating loads of the properties following the pattern:
private readonly MyType sth;
public MyClass(MyType sth) //class constructor
{
this.sth = sth;
}
public MyType Sth
{
get { return sth; }
}
Is there an easy way to automate creating of these properties? Usually I:
type the field, including the readonly keyword
Select "initialize from constructor parameters
Select "encapsulate"
Is it possible to make it quicker?
With C# 6, your example can be rewritten as:
private MyType sth { get; }
public MyClass(MyType sth) //class constructor
{
this.sth = sth;
}
This is called a getter-only auto-property. The generated field behind the property is declared read-only when you remove the "private set;" like this.
From https://msdn.microsoft.com/en-us/magazine/dn879355.aspx
Getter-only auto-properties are available in both structs and class declarations, but they’re especially important to structs because of the best practice guideline that structs be immutable. Rather than the six or so lines needed to declare a read-only property and initialize it prior to C# 6.0, now a single-line declaration and the assignment from within the constructor are all that’s needed. Thus, declaration of immutable structs is now not only the correct programming pattern for structs, but also the simpler pattern—a much appreciated change from prior syntax where coding correctly required more effort.
Please consider this live template:
private readonly $MyType$ $FieldName$;
public $ClassName$($MyType$ $FieldName$) //class constructor
{
this.$FieldName$ = $FieldName$;
}
public $MyType$ $PropName$
{
get { return $FieldName$; }
}
where the order of parameters is:
PropName
ClassName (in Choose Macro select "Containing type name")
MyType
FieldName (in Choose Macro select "Value of another variable with the first character in lower case" and then specify PropName there) - also select "Not editable" in right-top dropdown
It should look like this http://screencast.com/t/aRQi0xVezXMb
Hope it helps!
You can take advantage of automatic getters and setters to make the code a little cleaner
public readonly MyType Sth {get; private set;}
public MyClass(MyType sth)
{
Sth = sth;
}
I use this R# template (named prop):
public $TYPE$ $NAME$ { get; private set; }
It will not take you all the way and if you need readonly and readonly is nice.
An alt + enter option 'To readonly' would be sweet.
A way is alt + enter > 'To property with backing field' then delete the setter + add readonly. Not very automatic.
public class A {
public Par mParams;
public Par Parameters {
get { return mParams; }
set { mParams = value; }
}
}
I am new to c#
What is public Par Parameters? This seems neither a class or a function. Confused here.
Think of it like a public Par getParameters() and public void setX(Par p) method in Java. So, it is closest to a "function" but it is actually called Property. You can use it like this:
A myObject = new A();
a.Parameters = new Par(...);
This is a property which is backed by a public field, in this case, it is somewhat redundant, mParms should be declared as protected or private.
I recommend that you review this MSDN Programming Guide on Properties. It explains quite well, how they work and what they're used for.
The block of code from Public Par Parameters is a Property
I suspect the line public Par mParams; should actually be private. Its meant to be the underlying variable storing the value of the property.
Its worth pointing out that you do not explicitly need mParams any more in C#. You can define an automatic property, where the compiler creates its own underlying private variable using:
Public Par Parameters { get; set; }
public Par Parameters is a property, used to set or get the value of mParams.
Parameters is a Property of type Par. It has an access modifier (public), which means it is accessible from anywhere in your code.
Your example is a little redundant, because the mParams field is actually publicly accessible, and the property that exposes it doesn't do anything apart from returning and setting the field. However, you could potentially add extra code in each of the "accessors" (the get and set bits). For example to do validation, notify something that a property has been changed, etc.
You use properties in much the same way as fields:
A foo = new A();
// Calls the "get" accessor of the Parameters property
if (foo.Parameters == null)
{
// Calls the "set" accessor of the Parameters property
foo.Parameters = new Par();
}
It is considered a best practice to not allow direct access to member fields (variables) from outside a class. In a typical scenario, the field should therefore be private (or sometimes protected):
private Par mParams;
public Par Parameters
{
get { return mParams; }
set { mParams = value; }
}
There are a few slightly different syntaxes you will want to learn about as well. First, there is the auto-implemented property:
public Par Parameters
{
get;
set;
}
For auto-implemented properties, the C# compiler generates a backing field for you automatically. This saves you from writing some code if our property getter and setter don't need to contain any logic.
You can also use properties to restrict access in ways you cannot achieve with fields:
public Par Parameters
{
get;
private set;
}
Notice the set "accessor" has it's own access modifier. The result is a property that is publicly readable, but only the class itself is allowed to set it. This is similar to:
private Par mParams;
public Par Parameters
{
get { return mParams; }
}
Which does effectively the same thing, but without an auto-implemented property.
In languages that do not support properties, all this would be achieved by creating two methods: GetParameters and SetParameters. In fact, the C# compiler generates some very similarly named methods in the background.
It's shorthand for accessors and mutators. In another example:
private int i = 0;
public int myNumber {
get { return i; }
set { i = value; }
}
Allows you to change the variable i. Like so in code:
className.myNumber = 20;
// className.i is now 20
It's a property, which works very much like a pair of methods (functions) whose only purpose is to give you access to the mParams field. As a bit of syntactic sugar, C# gives you the ability to assign and read to it much as you would a variable. Think of it as two methods, getParameters and setParameters, which you can't call directly, but which are invoked when you access Parameters.
Parameters = new Par(); //Works as though you had run: setParameters(new Par());
Par x = Parameters; //Works as though you had run: Par x = getParameters();
This allows you to use the shorter, more convenient and expressive variable-like syntax, but what you're actually doing is running two "invisible" methods created by the compiler.
I have an object that takes plenty of parameters to its constructor (from 9 to 13 depending on use).
I want to avoid the ugliness of new MyObject(param1, param2, param3 ... param13).
My first attempt was to create a class MyObjectParams with properties with public getters and setters, it gives something like that :
var objectParams = new MyObjectParams
{
Param1 = ...,
Param2 = ...,
...
};
I see some big projects like SlimDX for their PresentParameters use this design. It looks better. But the class is not immutable.
I'd like my MyObjectParams to be immutable while still using a clean construction style. This is how it would look like with an immutable class :
var objectParams = new MyObjectParams
(
param1,
param2,
...
);
Note: it's just the long constructor line broken into several, so it's cleaner but still not as readable as initializers.
I was thinking of using named parameters to get both an immutable class and a more or less clean code, but I'm not sure whether this actually is a good idea:
var objectParams = new MyObjectParams
(
param1: ...,
param2: ...,
...
);
Should I use named parameters? Can you think of a better approach to solve this problem?
Edited regarding an answer below: unfortunately, I don't really think the design is bad. The 9 parameters really are required and remain constant throughout the entire life of the object. I cannot provide a default value for them as it is completely usage-dependant.
Have you looked into designing a solution in which you wouldn't need this amount of parameters? Having a lot of parameters makes the code very tightly coupled which reduces maintainability. Maybe you can redesign a small amount of code to a design which better separates the responsibilities of the class?
I really like the way The Zen of Python says a few things:
Simple is better than complex.
Complex is better than complicated.
[...]
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
I believe that having a dedicated Options class of some kind with the exhaustive list of all possible parameters is a good idea. Allow your MyObject constructor to require an Options instance, and then store a reference to the instance as a field on MyObject and refer to its getters/setters. (Storing the reference will be much superior to trying to parse the options and transfer their values to the MyObject instance. Now that would be messy.) With all data access delegated to the Options class, you will have successfully encapsulated the object's configuration, and you've designed a simple API for option access as the same time.
If Options has no reason to be publicly accessible, make it a private class definition and then you're free to maintain changes to Options logic without modifying MyObject. I believe that is a fair solution to you as the developer, and doesn't commit atrocities.
The constructor could have only a small number of parameters, the ones required for proper object initialization. You could then have a number of properties that can be set after the object has been constructed. You can set default values for those properties in the constructor and the client can set the ones he/she requires.
class Person
{
public Person(string name, int age)
{
Name = name;
Age = age;
Address = "Unknown";
Email = "Unknown";
}
public string Name {get; private set;}
public int Age {get; private set;}
public string Email {get; set;}
public string Address {get; set;}
}
Person p = new Person("John Doe", 30);
p.Email = "john.doe#example.org";
You could use the builder pattern to construct an immutable object.
public sealed class ComplexObject
{
public int PropA { get; private set; }
public string PropB { get; private set; }
public sealed class Builder
{
int _propA;
string _propB;
public Builder SetPropA(int propA)
{
// validate
_propA = propA;
return this;
}
public Builder SetPropB(string propB)
{
// validate
_propB = propB;
return this;
}
public CustomObject ToCustomObject()
{
return new CustomObject
{
PropA = _propA,
PropB = _propB
};
}
}
}
Usage
var custom =
new CustomObject.Builder()
.SetPropA(1)
.SetPropB("Test")
.ToCustomObject();
Final Thoughts
Despite my previous suggestion I am in no way against using named parameters if they are available.
I need to implement a read only property on my type. Moreover the value of this property is going to be set in the constructor and it is not going to be changed (I am writing a class that exposes custom routed UI commands for WPF but it does not matter).
I see two ways to do it:
class MyClass
{
public readonly object MyProperty = new object();
}
class MyClass
{
private readonly object my_property = new object();
public object MyProperty { get { return my_property; } }
}
With all these FxCop errors saying that I should not have public member variables, it seems that the second one is the right way to do it. Is this correct?
Is there any difference between a get only property and a read only member in this case?
The second way is the preferred option.
private readonly int MyVal = 5;
public int MyProp { get { return MyVal;} }
This will ensure that MyVal can only be assigned at initialization (it can also be set in a constructor).
As you had noted - this way you are not exposing an internal member, allowing you to change the internal implementation in the future.
C# 6.0 adds readonly auto properties
public object MyProperty { get; }
So when you don't need to support older compilers you can have a truly readonly property with code that's just as concise as a readonly field.
Versioning:
I think it doesn't make much difference if you are only interested in source compatibility.
Using a property is better for binary compatibility since you can replace it by a property which has a setter without breaking compiled code depending on your library.
Convention:
You are following the convention. In cases like this where the differences between the two possibilities are relatively minor following the convention is better. One case where it might come back to bite you is reflection based code. It might only accept properties and not fields, for example a property editor/viewer.
Serialization
Changing from field to property will probably break a lot of serializers. And AFAIK XmlSerializer does only serialize public properties and not public fields.
Using an Autoproperty
Another common Variation is using an autoproperty with a private setter. While this is short and a property it doesn't enforce the readonlyness. So I prefer the other ones.
Readonly field is selfdocumenting
There is one advantage of the field though:
It makes it clear at a glance at the public interface that it's actually immutable (barring reflection). Whereas in case of a property you can only see that you cannot change it, so you'd have to refer to the documentation or implementation.
But to be honest I use the first one quite often in application code since I'm lazy. In libraries I'm typically more thorough and follow the convention.
With the introduction of C# 6 (in VS 2015), you can now have get-only automatic properties, in which the implicit backing field is readonly (i.e. values can be assigned in the constructor but not elsewhere):
public string Name { get; }
public Customer(string name) // Constructor
{
Name = name;
}
private void SomeFunction()
{
Name = "Something Else"; // Compile-time error
}
And you can now also initialise properties (with or without a setter) inline:
public string Name { get; } = "Boris";
Referring back to the question, this gives you the advantages of option 2 (public member is a property, not a field) with the brevity of option 1.
Unfortunately, it doesn't provide a guarantee of immutability at the level of the public interface (as in #CodesInChaos's point about self-documentation), because to a consumer of the class, having no setter is indistinguishable from having a private setter.
In C# 9, Microsoft introduced a new way to have properties set only on initialization using the init accessor, like so:
public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
}
This way, you can assign values when initializing a new object:
var person = new Person
{
Firstname = "John",
LastName = "Doe"
}
But later on, you cannot change it:
person.LastName = "Denver"; // throws a compiler error
You can do this:
public int Property { get { ... } private set { ... } }
I agree that the second way is preferable. The only real reason for that preference is the general preference that .NET classes not have public fields. However, if that field is readonly, I can't see how there would be any real objections other than a lack of consistency with other properties. The real difference between a readonly field and get-only property is that the readonly field provides a guarantee that its value will not change over the life of the object and a get-only property does not.
yet another way (my favorite), starting with C# 6
private readonly int MyVal = 5;
public int MyProp => MyVal;
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties#expression-body-definitions
The second method is preferred because of the encapsulation. You can certainly have the readonly field be public, but that goes against C# idioms in which you have data access occur through properties and not fields.
The reasoning behind this is that the property defines a public interface and if the backing implementation to that property changes, you don't end up breaking the rest of the code because the implementation is hidden behind an interface.