I was wondering if there was a way to scope access of a class member specifically to get/set implementations in c# to reduce the chance of me accidentally accessing them directly. Something like private but only allows get/set to access it, I was thinking that I could wrap each variable in their own class but that seems overkill for the restriction I'm looking for. Thanks
-
Are there any other types of access than get and set? – GolezTrol Feb 13 '11 at 18:35
-
Surely (in most cases) you will need to do more with a particular class member than simply set and get it? It must influence object behaviour in some way, no? – Oliver Charlesworth Feb 13 '11 at 18:36
-
If you feel the need to protect a private variable from access from some of the class' methods, I'd say that it is a sign of your class having more than one responsibility. – Anders Abel Feb 13 '11 at 18:39
-
@Anders Abel - This could quite possibly be my problem. I think I have a tenancy to make single classes handle more than they should. Probably something I should work on improving in the future. – hookeslaw Feb 13 '11 at 18:56
4 Answers
You can add [Obsolete("Use the property")]
to the field and suppress the warning in the property by writing #pragma warning disable 618
.

- 868,454
- 176
- 1,908
- 1,964
No, unfortunately not. I assume you'd be after something like this:
// Not actually valid C#!
public string Name
{
// Only accessible within the property
string name;
get { return name; }
set
{
if (value == null)
{
throw new ArgumentNullException();
}
name = value;
}
}
I've wanted something like this before, too. Unfortunately it's not possible :(

- 1,421,763
- 867
- 9,128
- 9,194
-
but we can have something similar with auto implemented properties.. at least we don't have a variable to store val.. however we can neither specify our get set implementations – Shekhar_Pro Feb 13 '11 at 18:41
-
It would be nice if in the context of the property we'd have some sort of `field` keyword that would be a reference to the property's backing field. Or maybe this solution is good enough? I recently watched a talk you gave at NDC for your C#5 ideas - really cool ideas. – TheCloudlessSky Feb 13 '11 at 23:32
-
@TheCloudlessSky: That would be a possibility, but it would restrict the representation to a single field. What if you want two fields for some reason? (e.g. two individual values to make up a point). I don't think this is likely to happen any time soon, btw. – Jon Skeet Feb 13 '11 at 23:34
-
Yeah that's a very good point. I *hope* there is more support for immutability like F# - but I doubt that will happen. – TheCloudlessSky Feb 13 '11 at 23:36
-
I stumbled upon an interesting possiblity by using lambdas. :) I [clarify it in my updated answer](http://stackoverflow.com/questions/4986023/restricting-scope-of-a-class-member-beyond-private/4986143#4986143). – Steven Jeuris Jun 07 '11 at 01:26
This is not possible. The only access modifiers are private
, internal
, protected
, protected internal
and public
and none fit the bill.
If you use an auto-property, however, then of course you can only access it by get and set.

- 236,483
- 35
- 423
- 525
If you don't need to do any operations in the accessors, use a auto-implemented property.
I'm guessing most likely you DO want to do operations and that's why you want to make sure you use the property instead of the backing field.
In that case consider the following:
- Use a naming convention like "_instanceName" to indicate a private member field. (You should be doing this anyhow ...)
- When you feel the operations inside your accessors are common, and reuseable, encapsulate it in a class. Don't worry about overkill until you run into performance issues.
I believe I might have found a possible workaround, and it is surprisingly small. This 'solution' might be a bit too clever however. Perhaps I'll do some benchmarking tests tomorrow. Problem is at the moment it is also scoped over every place it is used, perhaps by using generics this can be limited.
It makes use of the fact that lambdas always have the same backing method. By passing a lambda to a static constructor, a static object can keep track of this unique 'scope' and link variables to it. More details about this implementation can be found here.
Usage:
class LocalTestClass
{
public int StaticTest( int setValue )
{
Local<int> test = Local<int>.Static( () => { } );
int before = test.Value;
test.Value = setValue;
return before;
}
public int InstanceTest( int setValue )
{
Local<int> test = Local<int>.Instance( () => this );
int before = test.Value;
test.Value = setValue;
return before;
}
}
[TestMethod]
public void LocalStaticTest()
{
LocalTestClass instance1 = new LocalTestClass();
LocalTestClass instance2 = new LocalTestClass();
instance1.StaticTest( 10 );
Assert.AreEqual( 10, instance2.StaticTest( 20 ) );
Assert.AreEqual( 20, instance1.StaticTest( 30 ) );
}
[TestMethod]
public void LocalInstanceTest()
{
LocalTestClass instance1 = new LocalTestClass();
LocalTestClass instance2 = new LocalTestClass();
instance1.InstanceTest( 10 );
Assert.AreEqual( 10, instance1.InstanceTest( 20 ) );
instance2.InstanceTest( 50 );
Assert.AreEqual( 20, instance1.InstanceTest( 30 ) );
}
The class:
public class Local<TValue>
{
static readonly Dictionary<object, object> StaticScope
= new Dictionary<object, object>();
static readonly Dictionary<object, Dictionary<object, object>> InstanceScope
= new Dictionary<object, Dictionary<object, object>>();
public TValue Value { get; set; }
private Local() { }
public static Local<TValue> Static( Action scope )
{
if ( !StaticScope.ContainsKey( scope ) )
{
Local<TValue> newInstance = new Local<TValue>();
StaticScope.Add( scope, newInstance );
}
return StaticScope[ scope ] as Local<TValue>;
}
public static Local<TValue> Instance<TScope>( Func<TScope> scope )
{
object instance = scope();
if ( !InstanceScope.ContainsKey( instance ) )
{
InstanceScope.Add( instance, new Dictionary<object, object>() );
if ( !InstanceScope[ instance ].ContainsKey( scope ) )
{
Local<TValue> newInstance = new Local<TValue>();
InstanceScope[ instance ].Add( scope, newInstance );
}
}
return InstanceScope[ instance ][ scope ] as Local<TValue>;
}
}
A more general discussion about this topic can be found on Programmers.SE.

- 1
- 1

- 18,274
- 9
- 70
- 161
-
I realized the instance scope variables aren't garbage collectioned anymore after the instance is no longer used. I'm playing around with weak references a bit to try to find a solution. – Steven Jeuris Jun 07 '11 at 13:35