I've been wondering for a while why C# doesn't support const on a class or a method level. I know that Jon Skeet have wanted support for immutability for a long time, and I recon that using the C++ syntax of function const could aid in that. By adding a const keyword on a class level we would have total support.
Now, my question is, what the reason is for the C# team to not have developed this kind of support?
I'd imagine everything could be created with a compile-time check or through attributes, without needing to change the CLR. I don't mind code being able to override the const behavior through reflection.
Imagine this:
const class NumberContainer
{
public int Number { get; }
}
.. Such a class could only be populated at construction time, so we'd need a constructor to take in an int.
Another example is const on a method-level:
public int AddNumbers(NumberContainer n1, NumberContainer n2) const
{
return n1.Number + n2.Number;
}
Const-level methods should not be able to alter state in their own class or instances of reference types passed to them. Also, const-level functions could only invoke other const-level functions while in their scope.
I'm not really sure if lambdas and delegates would make everything too hard (or impossible) to achieve, but I'm sure someone with more experience in language and compiler design could tell me.
As Steve B pointed out in the comments, the existence of readonly makes things a bit more complex, as const and readonly are close to the same during runtime, but readonly values can't be determined during compile-time. I guess we could have const and readonly level but that might be too confusing?
So, what's the reason for not implementing this? Usability concerns (understanding constness in C++ usually quite hard for new users), language design concerns (can't be done) or simply priority concerns (the days of the immutability-buzz are over)..?
Risking a somewhat circular explanation, C# doesn't support const because the CLR has no support for it whatsoever. The CLR doesn't support it because it is drastically non-CLS compliant.
There are very few languages that have the concept. The C language has support for const, that's well supported in C# by readonly keyword. But the big dog is of course C++ that has a much wider applicability for const, no doubt the one you are looking for. I'll avoid pinning down what const should mean, that's a wormhole in itself and just talk of "const-ness", the property of having const applied.
The trouble with const-ness is that it needs to be enforced. That's a problem in C# when an arbitrary other language can use a C# class and completely ignore const-ness just because the language doesn't support it. Bolting it onto every other CLS language just because C# supports it is of course very unpractical.
Enforceability is a problem in C++ as well. Because the language also supports const_cast<>. Any client code can cast the const-ness away swiftly and undiagnosably. You are not supposed to, but then sometimes you have to. Because there are two kinds of const-ness, strict and observable. Roughly analogous to private const-ness and public const-ness. The mutable keyword was added to the language later to try to deal with the need for observable const-ness so at least the inevitable usage of const_cast<> could be avoided. Some people say that C++ is a difficult language. Don't hear that of C# much.
You say the CLR wouldn't need to be changed, but consider that there's no standard way to express this "const"ness within compiled assemblies - and that these assemblies might not be consumed by C# code anyway. It's not something you can just do for C# - you'd have to do it for all .NET languages.
As I believe the case to be, const means different things in C# compared to C++.
In C# you can use the readonly keyword to get the level of functionality you're wanting from const.
I was once surpised by the following situation:
class Vector
{
private double[] m_data;
public int Dimension {get;set;}
public double this[int i]
{
get {return m_data[i];}
set {m_data[i] = value;}
}
public Vector(int n)
{
this.Dimension = n;
this.m_data = new double(n);
}
public static Vector Zero(int n)
{
Vector v = new Vector(n);
for (int i = 0; i < n; i++)
{
v[i] = 0.0;
}
return v;
}
public static readonly Vector Zero3 = Zero(3);
}
Thou Vector.Zero3 is readonly and you cannot assign to it, you can still access its component, and then the following stupid thing happens:
Vector a = Vector.Zero3;
a[0] = 2.87;
and now, since a ist nothing but a reference to Vector.Vector3 the latter also has Vector.Vector3[0] == 2.87!
After I fell into this pit once, I invented a very simple hack, though not being elegant, fulfills its function.
Namely, into a class that I suppose to produce static readonly "constants", I introduce a Boolean flag:
class Vector
{
private double[] m_data;
public int Dimension {get;set;}
private bool m_bIsConstant = false;
...
public double this[int i]
{
get {return m_data[i];}
set
{
if (!m_bIsConstant)
{
m_data[i] = value;
}
}
}
...
public static Vector Zero(int n)
{
Vector v = new Vector(n);
for (int i = 0; i < n; i++)
{
v[i] = 0.0;
}
v.m_bIsConstant = true;
return v;
}
...
}
This hack guarantees that your static readonly variable will never be modified.
In the case of your proposal for a const-class, you say:
Such a class could only be populated at construction time, so we'd need a constructor to take in an int
But by making all properties read-only anyway you have already achieved what you've said.
I cannot speak for the C# language designers but maybe the reason of not having const applied to lots of other constructs is because adding it was simply not worth the effort and you can get around the issue in other ways (as described above and in other answers/comments).
I can't tell from your question, how this overloading of the const keyword would be especially beneficial.
Your first example could be rewritten legally as
public class NumberContainer
{
private readonly int number;
public NumberContainer(int number)
{
this.number = number;
}
public int Number
{
get { return number; }
}
}
Perhaps, if the compiler is unable to discern the immutability of this class (I don't know), some attribute could be useful?
In your second example, I do not understand what you are driving at. If a function returns a constant value then it can be replaced with a constant field.
Related
This question already has answers here:
Is it possible to have a getter for a const?
(4 answers)
Closed 5 years ago.
I am just wondering if I have a constant attribute, can I set a public property to encapsulate it?
e.g.
private const int DEFAULT_CHARGE = 200;
public int default_charge
{
get { return DEFAULT_CHARGE; }
}
I don't get any errors but if something is constant I don't really understand the logic of why we encapsulate it. I really want to understand why this is:
right/wrong
why do it?
benefits?
It's important to know that constants are inlined by the compiler. It means that these two examples result in the same program:
private const int DEFAULT_CHARGE = 200;
public int default_charge
{
get { return DEFAULT_CHARGE; }
}
Is the same as this, after compiling:
public int default_charge
{
get { return 200; }
}
As you can see, the reference to DEFAULT_CHARGE is lost after compiling. That is important to remember for solutions where you reuse the same constants in multiple projects.
Let's say you use DEFAULT_CHARGE as a public const in LibA and LibB. Your project manager tells you to change the value from 200 to 300. Instinctively, you go to LibA where DEFAULT_CHARGE is defined, you change it to 300 and then you re-compile and deploy only LibA.
The result is that LibA now uses the new value of 300 but LibB keeps using the old value of 200, because the constant was baked into the DLL at compile-time.
The reason why you might encapsulate the constant is so that you can more easily change the value. Requirements tend to change over time. A DEFAULT_CHARGE value that is constant today might have to be replaced by a configuration value in the future.
By encapsulating the constant, you also prevent the problem that I just explained. If both LibA and LibB (and LibX, LibY,LibZ,...) depend on the encapsulation, you only need to recompile and deploy LibA to set the default charge in all dependent programs.
Even if something is constant you could still want control over how it is returned to the caller. If you have a have a Double variable that is store to 5 decimal places you could want to return the value to the caller in 2 decimal places. Encapsulation helps you get this control over your fields.
So you might need to encapsulate a constant field like this
private const double DEFAULT_CHARGE = 200.12345;
public int default_charge
{
get { return Math.round(DEFAULT_CHARGE,2); }
}
You may want to implement interface, abstract class etc.:
public interface IChargable {
int default_charge {get;}
}
public class MySimpleChargable: IChargable {
private const int DEFAULT_CHARGE = 200;
public int default_charge {get { return DEFAULT_CHARGE; }}
}
You may implement such a construction as a stub:
Initial:
// Version 1.0
public class MyChargable {
private const int DEFAULT_CHARGE = 200;
//TODO: implement (rare) "some condition" case
public int default_charge {get { return DEFAULT_CHARGE; }}
}
Later:
// Version 1.1
public class MyChargable {
private const int DEFAULT_CHARGE = 200;
public int default_charge {
get {
if (some condition)
return SomeComputation();
return DEFAULT_CHARGE;
}
}
It depends on your requirements.
In general, properties are designed to encapsulate any getting / setting logic you want, even calculable values or constants.
In my opinion, public property returning a value of a private constant is good in terms of architecture, in this case someone who uses your code doesn't know that he works with constant at all, i.e. he is abstracted from your implementation, and that's good. If you decide to make it not a constant, but configurable value, then you wouldn't expose it to your library consumer, you just make it like:
// private const int DEFAULT_CHARGE = 200; <-- is not used anymore
public int DefaultCharge
{
get { return SomeSortOfFileOrDatabaseConfiguration.DefaultCharge; }
}
or even
public int DefaultCharge
{
get
{
return CurrentUser.PersonalSettings.DefaultCharge;
}
}
which makes this code rely on users' personal settings without telling anything to your clients.
That's the main benefit. It is all about encapsulation and abstraction.
But please use proper naming for properties - it should be public int DefaultCharge, and pay attention to Jeroen Mostert's comment about constant inlining.
To my knowledge, you can create an public accessor to a private constant no problems.
You should create an accessor to a constant when:
You need to add extra logic to a getter like return it formated in some way or other value if a condition applies.
Your constant is part of a namespace that is used as library for other namespace, since if you compile the namespace on which the constant exists, the dependant namespace will only remember the old value of the constant, as it was defined on compilation.
Resharper recommended a change to my .net struct that I was unaware of. I am having a hard time finding Microsoft information about the this() initializer on a struct.
I have a constructor on my struct where i am passing in the values, but want the struct properties to be read-only to once the struct has been created. The Resharper proposed way makes the code much cleaner looking.
Questions:
Memory: I want to avoid generating any extra garbage if possible. I worry using this() may pre-initialize my value types, prior to setting them.
Performance: I worry that using the this() will first initialize the struct values with defaults, then set the values. An unnecessary operation. It would be nice to avoid that.
Cleanliness: Its obvious that using the :this() makes the struct much cleaner. Any reason why we wouldn't want to use that?
Example:
public struct MyContainer
{
public MyContainer(int myValue) : this()
{
MyValue = myValue;
}
public int MyValue { get; private set; }
}
public struct MyContainer2
{
private readonly int _myValue;
public MyContainer2(int myValue)
{
_myValue = myValue;
}
public int MyValue
{
get { return _myValue; }
}
}
If you are trying to optimize performance and less .net garbage, which is the correct route to go? Is there even a difference when it gets compiled?
I don't want to blindly accept using this, when I am creating millions of structs for data processing. They are short lived container objects so .net garbage and performance matters.
I create a quick benchmark of a struct with the "this()" initializer and one without, like this:
struct Data
{
public Data(long big, long big2, int small)
{
big_data = big;
big_data2 = big2;
small_data = small;
}
public long big_data;
public long big_data2;
public int small_data;
}
I benchmarked by initializing 5 billion structs of each type. I found that in debug mode, the struct test without "this()" initializer was measurably faster. In release mode, they were almost equal. I am assuming that in release mode, the "this()" is being optimized out and in debug it is running the "this()" and possibly even initializing the struct fields to default.
This is a short coming of the language concerning auto implemented properties and structs. It's fixed in C# 6 where the explicit call to this is not necessary , and you could even do away with the private setter:
public struct MyContainer
{
public int MyValue { get; }
public MyContainer(int value)
{
MyValue = value; //readonly properties can be set in the constructor, similar to how readonly fields behave
}
}
As to performance. I'd be very much surprised if there is a noticeable difference between the two (I can't currently check the differences in the generated IL). (As per comments, the next bit of the answer is irrelevant, calling this() will not generate additional "garbage") Also, if the objects are short lived like you claim, I wouldn't worry about garbage at all as they would all be stored in the stack, not the heap memory.
I encountered this FxCop rule before and wasn't really content with how to solve violations (thread1, thread2). I now have another case where I need to correct violations of the CA1819 kind.
Specifically, I have an algorithm-library that performs some analytic calculations on a curve (x,y), with a public "input object" like this:
public class InputObject
{
public double[] X { get; set; }
public double[] Y { get; set; }
// + lots of other things well
}
This object's X and Y properties are used in hundreds of locations within library, typically using indexes. The input object is never altered by the algorithms, but actually it shouldn't matter if so. Also, .Length is called pretty frequently. It's a mathematical library, and double[] is kind of the standard data type in there. In any case, fixing CA1819 will require quite some work.
I thought about using List<double>, since Lists support indexing and are quite similar to arrays but I'm not sure whether this may slow down the algorithms or whether FxCop will be happy with those Lists.
What is the best option to replace these double[] properties?
If it is read only to external consumer and consumer does not want to access it by index then the best is to have a public read only property of type IEnumerable<> with method accessors to add and remove, this way you will not have to expose your array to someone to mess with.
If you need to access the indexers then expose it as read only property of type IList<> and probably return a ReadOnly instance, with methods to add and remove.
This way you keep encapsulation of the internal list and allow consumer to access it in a read only way
Sometime FxCop from my point of view exagerates.
It all depends on what you have to do, if you are writing a complex system where security and very clean code is required, you should returns a readonly version of that array.
That is, cast the array as IEnumerable as suggests devdigital or use the good idea ImmutableArray of Mohamed Abed, that i prefer.
If your are writing software that require high performance... there is nothing better than an array for performances in C#.
Arrays can be a lot more performant for iterating and reading.
If performances are really important I suggest you to ignore that warning.
Is still legal, also if not too much clean, to return a readonly array.
for (int i = 0; i < array.Length; ++i) { k = array[i] + 1; }
This is very fast for big arrays in C#: it avoids array bounds check.
It will perform very much as a C compiled code would do.
I always wished a "readonly array" type in C# :) but there is no hope to see it.
As your link suggests:
To fix a violation of this rule, either make the property a method or
change the property to return a collection.
Using a collection such as a List should not have a significant impact on performance.
The big problem here isn't really what your library does with the values (which is a potential problem, albeit a much more manageable one), but rather what callers might do with the values. If you need to treat them as immutable, then you need to ensure that a library consumer cannot change the contents after their original assignment. The easy fix here would be to create an interface that exposes all the array members that your library uses, then create an immutable wrapper class for an array that implements this interface to use in your InputObject class. e.g.:
public interface IArray<T>
{
int Length { get; }
T this[int index] { get; }
}
internal sealed class ImmutableArray<T> : IArray<T>
where T : struct
{
private readonly T[] _wrappedArray;
internal ImmutableArray(IEnumerable<T> data)
{
this._wrappedArray = data.ToArray();
}
public int Length
{
get { return this._wrappedArray.Length; }
}
public T this[int index]
{
get { return this._wrappedArray[index]; }
}
}
public class InputObject
{
private readonly IArray<double> _x;
private readonly IArray<double> _y;
public InputObject(double[] x, double[] y)
{
this._x = new ImmutableArray<double>(x);
this._y = new ImmutableArray<double>(y);
}
public IArray<double> X
{
get { return this._x; }
}
public IArray<double> Y
{
get { return this._y; }
}
//...
}
The elements in your "immutable" array contents would still be mutable if T is mutable, but at least you're safe for the double type.
Change array [] to IEnumerable:
public class InputObject
{
public IEnumerable<double> X { get; set; }
public IEnumerable<double> Y { get; set; }
// + lots of other things well
}
UPDATE
The main questions remain the ones
under the example, but I guess it boils down
to :
**If you have a type where 99% of the values could be represented in one
fast, powerfull type, and only 1% in a
very heavy type, (say int vs.
BigInteger) How to represent it?? **
A school we learned a lot about internal representations, but never how to change it at runtime. I mean : suppose you have a class representing a decimal, but you use an integer to represent it internal, until you actually need a bigger value than the integer, and only than change representation...
I never thought of this before, and when thinkihng of it, I thought that would never work, since all the checks would kill it. But I just did a test since I'm too curious for my own good and there do exist situations when changing of representation is more perormant : given this interface :
interface INumber
{
void add1000();
void SetValue(decimal d);
decimal GetValue();
}
I found the latter of the two implementations to be more powerful in a lot of situations, including this one that I composed to attract as many ideas I could on the matter (not rep, it's community)
1. Representation by only a decimal
public class Number1:INumber
{
private decimal d { get; set; }
public void add1000()
{
d += 1000;
}
public decimal GetValue()
{
return d;
}
public void SetValue(decimal d)
{
this.d = d;
}
}
2. Representation by a decimal and an int
public class Number2:INumber
{
private bool usedecimal;
private int i;
private decimal d;
public void add1000()
{
if (usedecimal)
{
d += 1000;
return;
}
i += 1000;
if (i > 2147480000)
{
d = i;
usedecimal = true;
}
}
public void SetValue(decimal d)
{
try
{
i = (int)d;
}
catch (OverflowException e)
{
this.d = d;
}
}
public decimal GetValue()
{
return Math.Max(i,d);
}
}
}
My question is the following :
This seems sth. I have been missing, but this must be the bleeding obvious. Can anyone help me out with this?
Are there guidelines for mixed representations, when to use them, when not?
How to have a hunch when a mixed represtenation can be faster without benchmarking?
Any examples?
Any patterns?
Any ideas on the matter?
If you have a type where 99% of the values could be represented in one fast, powerfull type, and only 1% in a very heavy type, (say int vs. BigInteger) How to represent it??
BigInteger implementations typically do exactly that; they keep everything in ints or longs until something overflows, and only then do they go to the heavierweight implementation.
There's any number of ways to represent it. A pattern I like is:
public abstract class Thing
{
private class LightThing : Thing
{ ... }
private class HeavyThing : Thing
{ ... }
public static Thing MakeThing(whatever)
{ /* make a heavy or light thing, depending */ }
... etc ...
}
Are there guidelines for mixed representations, when to use them, when not?
Sure. We can easily compile such a list. This technique makes sense if:
(1) the lightweight implementation is much lighter than the heavyweight implementation
(2) the typical usage falls into the lightweight code path most of the time
(3) the cost of detecting the transition is not a significant cost compared to the cost of the heavyweight solution
(4) the more complex two-representation solution is necessary in order to achieve a customer-focused, realistic performance goal.
How to have a hunch when a mixed represtenation can be faster without benchmarking?
Don't. Making performance decisions based on hunches is reasoning in advance of facts. Drive performance decisions on realistic, customer focused, data-driven analysis, not on hunches. If I've learned one thing about performance analysis over the years its that my hunches are usually wrong.
Any examples?
Any number of implementations of BigInteger.
Any patterns?
Beats the heck out of me. I'm not much of one for memorizing pattern taxonomies.
Any ideas on the matter?
See above.
Perhaps you're looking for the Bridge pattern.
Sometimes you have a private field that backs a property, you only ever want to set the field via the property setter so that additional processing can be done whenever the field changes. The problem is that it's still easy to accidentally bypass the property setter from within other methods of the same class and not notice that you've done so. Is there a way in C# to work around this or a general design principle to avoid it?
IMHO, it is not used, because:
The class must trust itself
If your class gets as large that one part does not know the other, it should be divided.
If the logic behind the property is slightly more complex, consider to encapsulate it in an own type.
I'd consider this a nasty hack and try to avoid it if possible, but...
You can mark the backing field as obsolete so that the compiler will generate a warning when you try to access it, and then suppress that warning for the property getter/setter.
The warning codes that you'd need to suppress are CS0612 for the plain Obsolete attribute and CS0618 if the attribute has a custom message.
[Obsolete("Please don't touch the backing field!")]
private int _backingField;
public int YourProperty
{
#pragma warning disable 612, 618
get { return _backingField; }
set { _backingField = value; }
#pragma warning restore 612, 618
}
There's no inbuilt way to do what you want to do, but by the sounds of things you need another layer of abstraction between your class and that value.
Create a separate class and put the item in there, then your outer class contains the new class, and you can only access it through its properties.
No, there isn't. I'd quite like this myself - something along the lines of:
public string Name
{
private string name; // Only accessible within the property
get { return name; /* Extra processing here */ }
set { name = value; /* Extra processing here */ }
}
I think I first suggested this about 5 years ago on the C# newsgroups... I don't expect to ever see it happen though.
There are various wrinkles to consider around serialization etc, but I still think it would be nice. I'd rather have automatically implemented readonly properties first though...
You CAN do this, by using a closure over a local in the constructor (or other initialisation function). But it requires significantly more work that the helper class approach.
class MyClass {
private Func<Foo> reallyPrivateFieldGetter;
private Action<Foo> reallyPrivateFieldSetter;
private Foo ReallyPrivateBackingFieldProperty {
get { return reallyPrivateFieldGetter(); }
set { reallyPrivateFieldSetter(value); }
}
public MyClass() {
Foo reallyPrivateField = 0;
reallyPrivateFieldGetter = () => { return reallyPrivateField; }
reallyPrivateFieldSetter = v => { reallyPrivateField = v; };
}
}
I suspect that the underlying field type Foo will need to be a reference class, so the two closures are created over the same object.
There is no such provisioning in C#.
However I would name private variables differently (e.g. m_something or just _something) so it is easier to spot it when it is used.
You can put all of your private fields into a nested class and expose them via public properties. Then within your class, you instantiate that nested class and use it. This way those private fields are not accessible as they would have been if they were part of your main class.
public class A
{
class FieldsForA
{
private int number;
public int Number
{
get
{
//TODO: Extra logic.
return number;
}
set
{
//TODO: Extra logic.
number = value;
}
}
}
FieldsForA fields = new FieldsForA();
public int Number
{
get{ return fields.Number;}
set{ fields.Number = value;}
}
}
It just provides a level of obstruction. The underlying problem of accessing private backing fields is still there within the nested class. However, the code within class A can't access those private fields of nested class FieldForA. It has to go through the public properties.
Perhaps a property backing store, similar to the way WPF stores properties?
So, you could have:
Dictionary<string,object> mPropertyBackingStore = new Dictionary<string,object> ();
public PropertyThing MyPropertyThing
{
get { return mPropertyBackingStore["MyPropertyThing"] as PropertyThing; }
set { mPropertyBackingStore["MyPropertyThing"] = value; }
}
You can do all the pre-processing you want now, safe in the knowledge that if anyone did access the variable directly, it would have been really really hard compared to the property accessor.
P.S. You may even be able to use the dependency property infrastructure from WPF...
P.P.S. This is obviously going to incur the cost of casting, but it depends on your needs - if performance is critical, perhaps this isn't the solution for you.
P.P.P.S Don't forget to initialise the backing store! (;
EDIT:
In fact, if you change the value property stored to a property storage object (using the Command pattern for example), you could do your processing in the command object...just a thought.
Can't do this in standard C#, however you could
define a custom attribute say OnlyAccessFromProperty
write your code like
[OnlyAccessFromProperty(Name)]
String name
Name
{
get{return name;}
}
etc …
Then write a custom rule for FxCop (or another checker)
Add FxCop to your build system so if your custom rule find an error the build is failed.
Do we need a set of standard custom rules/attributes to enforce common design patens like this without the need to extend C#
C# has no language feature for this. However, you can rely on naming conventions, similar to languages which have no private properties at all. Prefix your more private variable names with _p_, and you'll be pretty sure that you don't type it accidentally.
I don't know C# but in Java you may have a base class with only private instance variables and public setters and getters (should return a copy of the instance var.) and do all other in an inherited class.
A "general design principle" would be "use inheritance".
There is no build in solution in C#, but I think your problem can be solved by good OO design:
Each class should have a single purpose. So try to extract the logic around your field into a class as small as possible. This reduces the code where you can access the field by accident. If you do such errors by accident, your class is probably to big.
Often interface are good to restrict access to only a certain "subset" of an object. If that's appropriate for your case depends on your setting of course. More details about the work to be done would help to provide a better answer.
You say that you do additional processing. Presumably this would be detectable under the correct conditions. My solution, then, would be to create unit tests that implement conditions such that if the backing field is used directly the test will fail. Using these tests you should be able to ensure that your code correctly uses the property interface as long as the tests pass.
This has the benefit that you don't need to compromise your design. You get the safety of the unit tests to ensure that you don't accidently make breaking changes and you capture the understanding of how the class works so that others who come along later can read your tests as "documentation."
Wrap it in a class? The property thing is a bit like that anyway, associating data with methods - the "Encapsulation" they used to rave about...
class MyInt
{
private int n;
public static implicit operator MyInt(int v) // Set
{
MyInt tmp = new MyInt();
tmp.n = v;
return tmp;
}
public static implicit operator int(MyInt v) // Get
{
return v.n;
}
}
class MyClass
{
private MyInt myint;
public void func()
{
myint = 5;
myint.n = 2; // Can't do this.
myint = myint + 5 * 4; // Works just like an int.
}
}
I'm sure I'm missing something? It seems too normal...
BTW I do like the closures one, superbly mad.
My favorite solution to this (and what I follow) is to name private backing fields that are never intended to be used directly with a leading underscore, and private fields that are intended to be used without the underscore (but still lowercase).
I hate typing the underscore, so if I ever start to access a variable that starts with the underscore, I know somethings wrong - I'm not supposed to be directly accessing that variable. Obviously, this approach still doesn't ultimately stop you from accessing that field, but as you can see from the other answers, any approach that does is a work around and/or hardly practical.
Another benefit of using the underscore notation is that when you use the dropdown box to browse your class, it puts all of your private, never-to-be-used backing fields all in one place at the top of the list, instead of allowing them to be mixed in with their respective properties.
As a design practice, you could use a naming convention for "private properties" that's different from normal public members - for instance, using m_ItemName for private items instead of ItemName for public ones.
If you're using the C# 3.0 compiler you can define properties which have compiler-generated backing fields like this:
public int MyInt { get; set; }
That will mean there is only one way to access the property, sure it doesn't mean you can only access the field but it does mean that there's nothing but the property to access.
I agree with the general rule that the class should trust itself (and by inference anybody coding within the class).
It is a shame that the field is exposed via intellisense.
Sadly placing [EditorBrowsable(EditorBrowsableState.Never)] does not work within that class (or indeed the assembly(1))
In Visual C#, EditorBrowsableAttribute does not suppress members from a class in the same assembly.
If you really do wish to solve this aspect of it the the following class may be useful and makes the intent clear as well.
public sealed class TriggerField<T>
{
private T data;
///<summary>raised *after* the value changes, (old, new)</summary>
public event Action<T,T> OnSet;
public TriggerField() { }
///<summary>the initial value does NOT trigger the onSet</summary>
public TriggerField(T initial) { this.data=initial; }
public TriggerField(Action<T,T> onSet) { this.OnSet += onSet; }
///<summary>the initial value does NOT trigger the onSet</summary>
public TriggerField(Action<T,T> onSet, T initial) : this(onSet)
{
this.data=initial;
}
public T Value
{
get { return this.data;}
set
{
var old = this.data;
this.data = value;
if (this.OnSet != null)
this.OnSet(old, value);
}
}
}
Allowing you to (somewhat verbosely) use it like so:
public class Foo
{
private readonly TriggerField<string> flibble = new TriggerField<string>();
private int versionCount = 0;
public Foo()
{
flibble.OnSet += (old,current) => this.versionCount++;
}
public string Flibble
{
get { return this.flibble.Value; }
set { this.flibble.Value = value; }
}
}
alternatively you can go for a less verbose option but accessing Flibble is by the not idiomatic bar.Flibble.Value = "x"; which would be problematic in reflective scenarios
public class Bar
{
public readonly TriggerField<string> Flibble;
private int versionCount = 0;
public Bar()
{
Flibble = new TriggerField<string>((old,current) => this.versionCount++);
}
}
or solution if you look at the community content!
The new Lazy class in .net 4.0
provides support for several common
patterns of lazy initialization
In my experience this is the most common reason I wish to wrap a field in a private properly, so solves a common case nicely. (If you are not using .Net 4 yet you can just create your own “Lazy” class with the same API as the .Net 4 version.)
See this and this and this for details of using the Lazy class.
Use the "veryprivate" construct type
Example:
veryprivate void YourMethod()
{
// code here
}