This question already has answers here:
Struct constructor: "fields must be fully assigned before control is returned to the caller."
(5 answers)
Auto-properties and structs
(3 answers)
Closed 9 years ago.
The following code suggests I cannot use implicit properties with a struct:
public struct LimitfailureRecord
{
public LimitfailureRecord(string sampleCode)
{
SampleCode = sampleCode;
}
public string SampleCode {get; set;}
{
}
}
It fails to compile, with the error message
"Backing field for automatically implemented property
'blahblah.LimitfailureRecord.SampleCode'
must be fully assigned before control is returned to the caller.
Consider calling the default constructor from a constructor
initializer."
If I change the struct to a class it's fine.
What do I need to do to make this work as a struct? I'd rather not go to the lengths of backing fields (this is a heavily stripped down version of the real code) if I can avoid it.
With structs you have to call the default constructor in all other constructors:
public LimitfailureRecord(string sampleCode) : this()
{
SampleCode = sampleCode;
}
Use a constructor chaining like so:
public LimitfailureRecord(string sampleCode)
: this()
{
...
}
The reason is the auto-implemented property introduces a (generated) instance field for backing, as described. All instance fields must be assigned to in an instance constructor of a struct.
Actually the error text you quote describes the fix pretty well.
Something else: If you keep the set accessor of your property public you will have a mutable struct. Most people agree that mutable structs should be avoided and are "evil" because their copy-by-value semantics and the possibility of mutating an existing struct value (as in record.SampleCode = "Here's a new string for an old object";) don't go well together. Check the threads on mutable and immutable structs.
You either need to call the default constructor or change the method name.
So;
public struct LimitfailureRecord
{
public void init(string sampleCode)
{
SampleCode = sampleCode;
}
public string SampleCode { get; set; }
}
Will work or just make the method definition; LimitfailureRecord(string sampleCode) : this()
The later is better because it only requires one call to make things work. If you go the init route you have do do new LimiFfailureRecord then call init after. structs in C# simply require you to call the default constructor, this isn't the case with classes which is why it will compile if you change it to a class.
Related
Update 1
It seems like either my English is terribly awful, or people just don't give a sh... to understand what I'm asking about or simply look at the title of the post.
C#5 specification clearly states:
Because the backing field is inaccessible, it can be read and written
only through the property accessors, even within the containing type.
This means that automatically implemented read-only or write-only
properties do not make sense, and are disallowed.
public string MyProperty {get;} has no sense, yet it costs nothing for compiler to emit getter not even warring about lacking setter. Backing field will be initialized with a default value. What does it mean? It means that designers spent some effort to implement a verification, to introduce functionality that could be left out.
Let's now consider C#6:
In C#6 the initialization of auto-implemented properties was introduced.
public string FirstName { get; set; } = "Jane";
or
public string FirstName { get; } = "Jane";
In the latter case property can be set in a constructor as well:
public class Program
{
public string ImagePath { get; }
public static void Main()
{
}
public Program()
{
ImagePath = "";
}
}
But only in constructor of the class where property was declared. Derived classes cannot set property's value.
Now ask yourself what this property means, if it was not initialized in constructor:
property string My {get;}
This is a 100% equivalent of C#5 prohibited property. It has no sense.
But such declaration being invalid in C#5 became valid in C#6. However semantics didn't change at all: this property is useless without explicit initialization.
That's why I am asking:
Why not explicitly initialized readonly auto-implemented property is valid in c# 6?
What I expect to see as an answer:
Either debunking of my initial assumptions about changes in C#6
Or the explanation of how and why compiler designers changed their mind
about what makes sense, and what does not.
I find the answer It's by design to be completely irrelevant. It is just a fact. I look for reasons. I don't believe compiler designers decide on changes in behavior of compiler with just tossing the coin.
This is an example of good answer.
Original question
In VS2015 this code is compiled without errors:
public class Program
{
public string ImagePath { get; }
public static void Main()
{
Console.WriteLine("Hello World");
}
}
However, in VS2013 I get error:
Compilation error (line 5, col 28): 'Program.ImagePath.get' must
declare a body because it is not marked abstract or extern.
Automatically implemented properties must define both get and set
accessors.
I know about initializable auto implemented properties, and in case of VS2015 field gets default value, that is null here. But then it's interesting to know why this snippet was invalid in C# 5?
Initializable auto-implemented readonly property left without explicit initialization seems to me a bit ODD. It is likely a mistake rather than intention. I'd personally prefer compiler to require explicit initialization in this case:
public string ImagePath { get; } = default(string);
Ok, I know that such property can be also assigned in constructor:
public class Program
{
public string ImagePath { get; }
public static void Main()
{
}
public Program()
{
ImagePath = "";
DoIt();
}
public void DoIt()
{
//ImagePath = "do it";
}
}
public class My : Program
{
public My()
{
//ImagePath = "asdasd";
}
}
But if compiler can check that local variable is not initialized, the same is possible for the property.
So why is it as it is?
The compiler is telling you that automatic properties must have both accessors defined. For example, you could fix the error with
public string ImagePath { get; private set; }
assuming that you do not intend the property to be settable outside the class.
As to why you have to declare a setter or manually implement the property -- well, what good would be a property that you can read from, but will always return the default value of its type since there is no way to set it? Conversely, what good would be a property you can write to but can neither read from nor hook into its setter?
C# 6.0 gives you the option of having write-once, read many auto-properties; this is a huge difference as the value can be arbitrarily chosen, allowing you convenient syntax for properties with immutable values.
I have no idea why your question have been down voted. This is interesting observation but please keep in mind that it is not a breaking change - it is just 'new functionality' that is 'leftover' of other functionality - initialization of auto-implemented properties.
That means it had no sense previously, but now it has.
Moreover, I think it has always had sense. E.g. when you have some base class or interface, for example
interface IPerson
{
int Age { get; }
}
Some day you may want to implement null-object pattern where the age is irrelevant. In c#5 you have to write public int Age { get { return 0; } }, while in c#6 you can simply do public int Age { get; } or even transform interface to abstract class changing only its definition from interface to abstract class.
This question already has answers here:
Any reason to use auto-implemented properties over manual implemented properties?
(7 answers)
Closed 9 years ago.
What is more "true": use properties with or without private fields.
I.e.
1.
class A
{
int _field;
public int Field
{
get{ return _field;}
set{_field = value;}
}
}
2.
class A
{
public int Field{get;private set;}
}
Number 2 creates a backing field automatically, so you always have a private field "behind the scenes" (although not directly accessible in the latter case).
when you create anonymous property compiler creates corresponding field for you, so it's pretty much the same, but you can access autocreated field only via property
It makes no difference - the compiler generates the property implementation for you in exactly the same way that it generates a default constructor or the code for a using statement. These two classes are nearly 100% equivalent which you can see if you decompile an auto-property (the only difference is the name of the generated backing field that the compiler uses)
class A
{
public int Field {get; private set;}
}
class A
{
int _field;
public int Field
{
get { return _field; }
private set {_field = value; }
}
}
Its completely down to your personal preference.
As has already been stated, the second creates the backing field at compile time. You would typically define a backing field your self if you wanted the property to act as a public accessor to the field, where you can add custom logic or prevent the value being modified (using the private keyword on the setter).
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
What is the difference between a field and a property in C#
Should I use public properties and private fields or public fields for data?
What is the difference between:
public string varA;
and
public string varA { get; set; }
The public property accessor gives you more flexibility in the future.
If you want to add validation to setting the value, you simply write a non-default setter. None of your other code would have to be modified.
There could also be reasons you'd want to replace the default getter with code. That can be a real pain with a public variable.
In addition to the other answers, you can also use a property to make the value read-only or even set-only:
public int Item { get; private set; } // read-only outside the class. Can only be set privately.
I have also run into situations where I later decide I want to proxy an object, or add AOP, which basically requires properties.
Public property accesses fields and internal class code through exposed getter and setter methods. A public field acesses the field directly.
Using propertys offers the potential to provide a layer of abstraction and design (ability to make set accessor protected, private).
When a property is specified and no body present an underlying private field is created by the compiler that is used to store the value against. Essentially:
private int item = 0;
public int Item {
get { return item; }
set {item = value; }
}
In general I tend to use properties for public exposed variables and fields for private. I might consider using a field if that field was accessed many times and speed was a crucial design requirement.
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Initialize class fields in constructor or at declaration?
We are arguing about coding practices. The examples here are a little too simple, but the real deal has several constructors. In order to initialise the simple values (eg dates to their min value) I have moved the code out of the constructors and into the field definitions.
public class ConstructorExample
{
string _string = "John";
}
public class ConstructorExample2
{
string _string;
public ConstructorExample2()
{
_string = "John";
}
}
How should it be done by the book? I tend to be very case by case and so am maybe a little lax about this kind of thing. However i feel that occams razor tells me to move the initialisation out of multiple constructors. Of course, I could always move this shared initialisation into a private method.
The question is essentially ... is initialising fields where they are defined as opposed to the constructor bad in any way?
The argument I am facing is one of error handling, but i do not feel it is relevant as there are no possible exceptions that won't be picked up at compile time.
Note that all such field declaration-level initialization will be performed once for each constructor-chain, even if the constructor by itself sets the field to something else.
If you chain constructors together, the fields will be initialized in the common, first, constructor that is called.
Look at this example:
using System;
namespace ClassLibrary3
{
public class Class1
{
private string _Name = "Lasse";
public Class1()
{
}
public Class1(int i)
: this()
{
}
public Class1(bool b)
{
_Name = "Test";
}
}
}
This code compiles as this:
using System;
namespace ClassLibrary3
{
public class Class1
{
private string _Name;
public Class1()
{
_Name = "Lasse"
}
public Class1(int i)
: this()
{
// not here, as this() takes care of it
}
public Class1(bool b)
{
_Name = "Lasse"
_Name = "Test";
}
}
}
It's not necessarily bad to initialize values outside of the constructor, and the problem you have here:
string _string;
public ConstructorExample2()
{
_string = "John";
}
Is that if you have multiple constructors you have to remember to either
1. Reinitialize _string in every constructor
2. Separate the logic out into a common method and call that method in every constructor
3. Call the constructor with the logic in it, from the other constructors. (Chain the constructors)
Now this isn't necessarily a problem, but you have to remember to do it. By initializing it outside of the constructor, it's done for you. It's one less thing you need to remember to do.
Microsoft FxCop by default recommends field initializers over using the constructor. This question is also a duplicate of this one and should provide some insight.
With static classes, you'll have to note some subtleties as addressed at this question.
In the above example the assignment of "John" to _string has no logical reliance on any variables and therefore it should be outside of the constructor in the field initializer.
So long as it is not possible to initialize the object in an non-usable state then it doesn't matter.
When the code is compiled both approaches will be the same anyway.
Not sure about C#, but in Java source code they seem to prefer the constructor, example:
public class String{
char[] value;
int offset;
...
public String(){
value = new char[0];
offset = 0;
...
}
}
I think for simple initializations like that it's fine to do it in the declaration. However, I don't understand the error handling argument. Even if there is an exception in the initialization, I think you will find that your normal error handling mechanism will work the same. It will still throw an exception when you call the constructor.
I tend to initialize things in the get accessor, where they are first used. If null then initialize and all that.
I prefer to initialize simple fields like that outside of the constructor.
It shouldn't cause any issues since compilation actually moves those initializations into the constructor at compile-time anyway.
If the initialization of the variable will be the same, no matter what arguments are passed to the constructor, then it doesn't make sense to clutter the constructor method with the unnecessary initialization code. In this case, I initialize in-place.
Inisialing the fields in the constructor is better. This way if/when a different constructor is added you know that all the fields are starting with null/default values and you can initialise them appropriately.