Eliminate Duplicate C# Property Bodies - c#

I am building a large, complex data structure with many interconnected objects. As part of this, I have a situation where I need to create an object before I know the values for all the properties. This is so I can pass a reference to that object around inside of a larger data structure, then change it later to allow all the consumers of that object to get the "updated" values.
Tracking the consumers of each object so I can go update their references means I am A) re-implementing a reference counting garbage collector and B) would require an external consumer to modify a class. For obvious reasons, I don't want to implement a garbage collector (or something similar). and allowing external consumers to modify properties means the object is mutable. Immutability is important because I know that many objects in this data structure are going to wind up in Dictionaries after the data structure has been built, but I can safely modify properties until then. Since this is going into a library that will be provided to other users, I must block interactions that will break things like invariants for Dictionaries.
I am implementing this "deferred initialization" concept for properties like this:
class MyClass
{
private AnotherClass mReference = null;
public bool Reference
{
get
{
return this.mReference
}
internal set
{
if ( this.mReference != null )
{
throw new Exception( "This value has already been initialized!" );
}
else
{
this.mReference = value;
}
}
}
}
I am allowing anything in the internal scope to assign a non-null value to this property exactly once. Once the property has been set, there's no going back.
While C# has a keyword readonly that sort of already does this, readonly constrains the member to only be assigned to via either a static initializer or a constructor in the same class. But at the time the constructor is called, I don't know what the value for this property is!
My problem is I am now using this exact pattern across multiple classes, and I would like to avoid this code duplication.
Does anyone have any suggestions for how I can reduce the code duplication? Maybe a C# keyword like readonly, or some other language feature? Or is this just not possible? Unfortunately, it is not possible to refactor the algorithms such that I can delay instantiation of all objects until all values are known. Think of bidirectional relationships with immutable objects at each end if you need an example of this scenario.

Just encapsulate the behavior in its own type:
public sealed class OneTimeAssignable<T> where T : class
{
public T Value
{
get
{
return mValue;
}
set
{
if( mValue != null ) throw new InvalidOperationException( "Value can only be assigned once." );
mValue = value;
}
}
private T mValue;
}
Now you can use it as the backing field for your properties:
class MyClass
{
private readonly OneTimeAssignable<AnotherClass> mReference = new OneTimeAssignable<AnotherClass>();
public AnotherClass Reference
{
get
{
return this.mReference.Value;
}
internal set
{
this.mReference.Value = value;
}
}
}
Right now I have it set to only work on reference types (and assuming you don't want them to ever be set to null), but it's easy enough to modify it to accept value types as well, but requires adding a bool to track whether the property has been set.

Related

MethodBase as Hashtable Key

I want to store some backing fields of Properties declared in derived classes in protected Hashtable contained in base class.
The usage of this mechanism in derived classes has to beas simple as possible.
So, can I use MethodBase.GetCurrentMethod() to provide information about calling property (getter - properties are read-only), so it can be recognized as the one and only property that has access to this particular backing field?
EDIT:
Basically, I want to implement pattern:
private SomeClass _someProperty = null;
private SomeClass SomeProperty
{
if (_someProperty == null)
{
_someProperty = new SomeClass();
}
return _someProperty;
}
to look something like this:
private SomeClass SomeProperty
{
return GetProperty(delegate
{
var someProperty = new SomeClass();
return someProperty;
};
}
And in base class
private System.Collections.Hashtable _propertyFields = new System.Collections.Hashtable();
protected T GetProperty<T>(ConstructorDelegate<T> constructorBody)
{
var method = new System.Diagnostics.StackFrame(1).GetMethod();
if (!_propertyFields.ContainsKey(method))
{
var propertyObject = constructorBody.Invoke();
_propertyFields.Add(method, propertyObject);
}
return (T)_propertyFields[method];
}
protected delegate T ConstructorDelegate<T>();
The reason I want to do this is to simplify the usage of properties.
I use private properties to create some objects and use them around the class. But when I store their backing fields in the same class, I have the same access to them as to the properties, so I (means user who would create some derived classes in the future) could accidently use backing field instead of the property, so I wanted to restrict access to backing field, while allow to create object and use it.
I tried to use ObsoleteAttribute on the backing fields like this:
[Obsolete("Don't use this field. Please use corresponding property instead.")]
private SomeClass __someProperty;
private SomeClass _someProperty
{
#pragma warning disable 0618 //Disable Obsolete warning for property usage.
get
{
if (__someProperty== null)
{
__someProperty = new SomeClass();
}
return __someProperty ;
}
#pragma warning restore 0618 //Restore Obsolete warning for rest of the code.
}
But, firstly, I cannot force the user to use this pattern, and secondly, it's to much code to write in derived class, which, as I metioned above, I want to be as simple as possible.
Neither MethodBase nor MemberInfo do not properly overrides Equals and GetHashCode functions, but uses default RuntimeHelpers.GetHashCode and RuntimeHelpers.Equals. So you will only be able to compare same instance, but not same content. In most cases this will be enough as runtime caches that instances to reuse them. But there is no guarantee this will work stable.
As you working with metadata, use something that will identify it uniquely. For example, MemberInfo.MetadataToken. You could write your own comparer and use it inside hashtable:
public class MethodBaseComparer : IEqualityComparer<MethodBase>
{
public bool Equals(MethodBase x, MethodBase y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
return false;
return x.MetadataToken.Equals(y.MetadataToken) &&
x.MethodHandle.Equals(y.MethodHandle);
}
public int GetHashCode(MethodBase obj)
{
return (obj.MetadataToken.GetHashCode() * 387) ^ obj.MethodHandle.GetHashCode();
}
}
It not a good idea to restrict access via reflection to some members as other trusted code can use reflection to access other private data outflanking your checks. Consider restrict access via redesigning your classes.
Also take a look at Code Access Security.
Update according to your edit.
You told your properties are read-only. I guess, simply declaring them as readonly is not your option. Looks like you want delayed initialization for properties values. In that case you will not able to declare them as readonly. Right?
Or maybe you can?
Take a look at Lazy<T> class. It's not available in dotnet 2.0, but you can easily implement it or even take any existing implementation (just replace Func<T> with your delegate). Example usage:
public class Foo
{
private readonly Lazy<int> _bar = new Lazy<int>(() => Environment.TickCount, true);
// similar to your constructorBody - ^^^^^^^^^^^^^^^^^^^^^^^^^^^
private int Bar
{
get { return this._bar.Value; }
}
public void DoSomethingWithBar(string title)
{
Console.WriteLine("cur: {0}, foo.bar: {1} <- {2}",
Environment.TickCount,
this.Bar,
title);
}
}
Pros:
It's a lazy initialization as you wish. Let's test it:
public static void Main()
{
var foo = new Foo();
Console.WriteLine("cur: {0}", Environment.TickCount);
Thread.Sleep(300);
foo.DoSomethingWithBar("initialization");
Thread.Sleep(300);
foo.DoSomethingWithBar("later usage");
}
Output will be something like this:
cur: 433294875
cur: 433295171, foo.bar: 433295171 <- initialization
cur: 433295468, foo.bar: 433295171 <- later usage
Note, value initialized on first access and not changed later.
Properties are write-protected by a compiler - _bar field is readonly and you have no access to internal fields of Lazy<T>. So, no any accidental backing field usage. If you try you will get compilation error on type mismatch:
CS0029 Cannot implicitly convert type System.Lazy<SomeClass> to SomeClass
And even if you access it via this._bar.Value, nothing terrible would happen and you will get a correct value as if you access it via this.Bar property.
It is much more simpler, faster and easier to read and maintain.
Thread safety out of the box.
Cons: — (I didn't found)
Few cents about your hashtable-based design:
You (or someone who will maintain your code) can accidentally (or advisedly) access and/or modify either whole hashtable or it's items as it is just a usual private property.
Hashtable is a minor performance hit + getting stacktrace is a huge performance hit. However I don't know if it is critical, depends on how often you access your properties.
It would be hard to read and maintain.
Not thread safe.

C# define that a class instance can never be null (it only contains no data)

Out of curiosity: Is there a way to create a class whose reference to the class instance can never be set to null?
Like haveing only a readonly pointer that can only be set to null by the class itself.
What I have in mind:
I would want to have an easy to read /use object that either exists with data or exists without (shown by an attribute like hasData = false). It is always accessable and should never be null / point to nowhere which as a side effect gets also rid of NullReferenceExceptions for objects that are sometimes supposed to not have a value without the need of checking for null.
This feature does not exists (yet). There is big discussion of non-nullable reference types at Roslyn forum: non-nullable reference types (the one billion $ mistake). But currently you cannot restrict reference type variable from assigning null value.
You can use value type (struct) instead, but it's not stored in heap, passed by value etc.
All other options will not guarantee that someone will not assign null to variable of your reference type. But you still can use something like Null Object pattern to simplify your life (processing objects without data in same way as usual objects).
In such a case, you may want to use a struct instead of a class. Class is a reference type and therefore its default value is null, hence a variable containing an instance can be nulled (assigned null). There is no way to prevent it. On the other hand, struct is a value type and default for struct is an empty struct - i.e. a struct whose members are set to their defaults (0 for an int field, null for a field of a reference type etc.)
Example of a struct
public struct Foo
{
public int Bar;
}
And its usage (notice it is not instantiated but still it is NOT null)
Foo foo;
foo.Bar = 1;
More about structs can be found here on the MSDN sites.
As Anton mentioned, you could use a struct which cannot have a default value of null. But I am thinking you want something more like this:
public class DataObject
{
public static bool HasData
{
get
{
return myObject != null;
}
}
public static DataObject PresistentDataObject
{
get
{
return myObject;
}
}
static DataObject myObject = new DataObject();
}
This code seems like bad practice. And maybe you'd want to resort to something like dependency injection with a singleton which will avoid setting up a state class like this.
Typically, the motivation behind such a question drives the qualities/properties of a solution.
Here, I suppose, the motivation is to avoid runtime exceptions of (faulty) code which tries to access a null reference as if it held an instance.
class Foo<T> {
T data; // might be null or hold an instance...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays(); // might return null...
}
bool DoSomething() {
return data.Value > 5; // might throw an exception...
}
// ... more members...
}
To prevent this type of errors, you could borrow from C#'s cousin language F#.
If the function T GetInstanceOfTInMysteriousWays<T>() by design and contract is permitted to either return an instance or a null value, a better design of that function would be to have it return not T but an Option<T>. Then, the type of Foo.data would not be T but Option<T> and the user code in DoSomething() could not simply access member data.Value. Thus, this common pattern of bugs would be eliminated.
// Improved code from above
class Foo<T> {
Option<T> data; // Option is a struct type and cannot be null...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays();
}
bool DoSomething() {
if (data.IsSome() ) {
return data.TryGetValue().Value > 5;
}
return false;
}
}
Now the only question is, where to find that Option type in C#? There are several github projects creating such a type (google is your friend). You could also consider to link the F# core library and use the Option type defined there, maybe along with a little helper as is shown in this gist snippet.
If your class is named foo, then you would have at least one constructor (possibly more). In that constructor you would assign the variable to false.
public foo(){
hasData = false;
}
As #Anton points out, this only works if the variable is instansiated.
foo f = new foo();
it would still be null if you assigned it as null:
foo f = null;
I'm not sure, I understand the question correctly or not. Let me add
some points here:
Hope that you misunderstand the term Instance, If you create an instance of the class then it will not be null, Let myClass be a class that you have created already. You are not creating any instance of the class by using myClass myClassObject. The myClassObject will became an instance of the class only when an instance of the class is assigned to it, Until then it is null which means not existing.
As others have mentioned, you'd need a struct for that.
However, we can tackle this from a different angle (in a class):
Since the variable can point to null, let's define the variable in a way that it can't be set to null:
private Class1 _c = new Class1();
public Class1 c { get { return _c; } set { if (value != null) _c = value; } }
so c will not be set to null.
A struct per your requirements:
struct Struct1
{
public bool hasData { get { return Data != null; } }
public Class1 Data;
}

Sharing a reference between objects

I want to have multiple objects share a reference through a private field, such that any of the objects can assign to the field, and the updated field will be seen by other objects sharing that reference. What I was originally hoping to do was this:
class SomeObject
{
private ref DataObject _data;
public SomeObject(ref DataObject data)
{
_data = ref data; // or something similar
}
public ChangeData(DataObject newData)
{
_data = data;
// at this point, *other* SomeObject instances that were
// created with the same reference should also have _data == newData
}
}
But of course you can't use ref that way: ref is only for method parameters. And a static field won't work, since not all SomeObject instances should refer to the same object---rather, the object in question should be set in the constructor.
Obviously I could solve this by just adding a simple wrapper class. But is there a better way? Is there some kind of SharedReference<T> class that I can use?
Update, since most of the answers misunderstood what I was asking. I know that the _data field contains a reference to the original DataObject. What I want is another level of indirection. I want to be able to change which object I'm pointing to in one instance, and have the new value be picked up by other instances that were created with the same reference. As the updated code sample shows, I want to assign to _data, and effectively change the value of _data in other instances.
I don't know of any class that you can use for this, but I seems quite easy to implement your own SharedReference<T> class.
Something like this:
public sealed class SharedReference<T>
where T : class
{
public T Reference
{
get; set;
}
}
You could simply use an array of shared objects, and reassign the array elements:
class SomeObject
{
// you probably want to make this readonly
private readonly DataObject[] _data;
public SomeObject(DataObject[] data)
{
_data = data;
}
public void ChangeData(DataObject newData)
{
_data[0] = o;
}
// and you could define your own accessor property...
private DataObject Data
{
get { return _data[0]; }
set { _data[0] = value; }
}
}
Apart from that, I think you'll need to define your own 'holder' class & use that
If you simply provide a reference to the object without the ref keyword, you will get the behaviour you want. Using ref is actually passing a reference to a reference (pointer to a pointer), so unless you want to null someone else's reference, it won't be of any use to you.
Update: Sorry I didn't spot that you wanted to re-assign a completely new object into the field and have that reflected throughout. You are best actually creating either a wrapper class to contain the object state and modify that, or a common event that all instances can subscribe to such that when you want to change the object, fire the event with the new object inside it and have each instance update it's own internal reference.
Alternatively, use the Singleton pattern - everyone accesses a publicly available static reference, but unlike the traditional Singleton, you let them change the reference if they want to - so everyone can see the change. This also has the benefit that the objects don't need internal references.
Alternatively again, have the data class expose a method allowing it to consume another data class and copy its state across - like cloning.
In C#,
class SomeObject
{
private DataObject _data;
public SomeObject(DataObject data)
{
_data = data;
}
}
in fact does exactly what you want, if DataObject is a Reference Type, which is true for all classes.
Please disregard this answer since I misunderstood the initial question.Other answers here cover the topic fully.

More private than private? (C#)

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
}

Acessing the backing field in an auto property

Is there any way to access the backing field for a property in order to do validation, change tracking etc.?
Is something like the following possible? If not is there any plans to have it in .NET 4 / C# 4?
public string Name
{
get;
set
{
if (value != <Keyword>)
{
RaiseEvent();
}
<Keyword> = value;
}
}
The main issue I have is that using auto properties doesn't allow for the same flexibility in validation etc. that a property with a explicit backing field does. However an explicit backing field has the disadvantage in some situations of allowing the class it is contained in to access the backing field when it should be accessing and reusing the validation, change tracking etc. of the property just like any other class that may be accessing the property externally.
In the example above access to the backing field would be scoped to the property thus preventing circumvention of the property validation, change tracking etc.
Edit: I've changed < Backing Field > to < Keyword >. I would propose a new keyword similar to value. field would do nicely although I'm sure it's being used in a lot of existing code.
No there isn't. If you want to access the backing field, then don't use auto properties and roll your own.
I agree that it would be great to have a field that was only accessible by the property and not by the rest of the class. I would use that all the time.
As the MSDN states:
"In C# 3.0 and later, auto-implemented
properties make property-declaration
more concise when no additional logic
is required in the property accessors.
They also enable client code to create
objects When you declare a property as
shown in the following example, the
compiler creates a private, anonymous
backing field can only be accessed
through the property's get and set
accessors."
Since you have additional logic in you accessors, the use of auto-implemented properties is not appropriate in your scenario.
While the backing field does exist, it is given a mangled name to stop you referencing it easily - the idea is that you never reference the field directly. For interests sake, you can use Reflector to disassemble your code and discover the field name, but I would recommend you not use the field directly as this name may indeed be volatile, so your code could break at any time.
Having read your comments in Mehrdad's answer, I think I understand your problem a bit better.
It appears that you are concerned about the ability of the developer to access private state in the class they are writing, bypassing your validation logic, etc. This suggests that the state should not be contained in the class at all.
I would suggest the following strategy. Write a generic class that represents a ValidatedValue. This class holds only the backing value and only allows access/mutation via get and set methods. A delegate is passed to the ValidatedValue to represent the validation logic:
public class ValidatedValue< T >
{
private T m_val;
public ValidationFn m_validationFn;
public delegate bool ValidationFn( T fn );
public ValidatedValue( ValidationFn validationFn )
{
m_validationFn = validationFn;
}
public T get()
{
return m_val;
}
public void set(T v)
{
if (m_validationFn(v))
{
m_val = v;
}
}
}
You could, of course, add more delegates as required (eg, to support pre/post change notification).
Your class would now use the ValidatedValue in place of a backing store for your property.
The example below shows a class, MyClass, with an integer that is validated to be less than 100. Note that the logic to throw an exception is in MyClass, not the ValidatedValue. This allows you to do complex validation rules that depend on other state contained in MyClass. Lambda notation was used to construct the validation delegate - you could have bound to a member function instead.
public partial class MyClass
{
private ValidatedValue<int> m_foo;
public MyClass()
{
m_foo = new ValidatedValue<int>(
v =>
{
if (v >= 100) RaiseError();
return true;
}
);
}
private void RaiseError()
{
// Put your logic here....
throw new NotImplementedException();
}
public int Foo
{
get { return m_foo.get(); }
set { m_foo.set(value); }
}
}
Hope that helps - somewhat off the original topic, but I think it's more inline with your actual concerns. What we have done is taken the validation logic away from the property and put it on the data, which is exactly where you wanted it.
No, but you can in a subclass:
public class Base
{
public string Name
{
get;
virtual set;
}
}
public class Subclass : Base
{
// FIXME Unsure as to the exact syntax.
public string Name
{
override set
{
if (value != base.Name)
{
RaiseEvent();
}
base.Name = value;
}
}
}
If you're gonna do so, why you are using auto properties?!
A simple property has done it way back in 1.0. I don't think it makes sense to add complexity to the language for every special case. You either need the property to do plain store/retrieve model or need more than that. In the latter case, a normal property will do.
You can't do this I'm afraid. That's one of the reasons I started writing MoXAML Power Toys, to provide the ability to convert automatic properties into Notify properties.

Categories

Resources