2011-02-13 79 views
3

我想知道是否有一种方法来限制类成员的访问,特别是在C#中获取/设置实现,以减少我直接意外访问它们的机会。像私人的东西,但只允许获取/设置访问它,我想我可以包装每个变量在他们自己的班级,但似乎矫枉过正,我正在寻找。谢谢限制类成员的范围超出私人的

+0

是否有任何其他类型的访问比获取和设置? – GolezTrol 2011-02-13 18:35:45

+0

当然(在大多数情况下)您需要对特定的班级成员做更多的事情,而不是简单地设置和获取它?它必须以某种方式影响对象行为,不是吗? – 2011-02-13 18:36:06

+0

如果你觉得有必要保护一个私有变量不受某些类的方法访问,那么我认为这是你的班级承担多项责任的标志。 – 2011-02-13 18:39:10

回答

3

不,不幸的不是。我想你会在这样的事情之后:

// 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; 
    } 
} 

我以前也想过类似的东西。不幸的是这是不可能的:(

2

这是不可能的。唯一的访问修饰符是private,internal,protected,protected internalpublic,并且没有符合该法案。

但是,如果您使用自动属性,那么您当然只能通过get和set来访问它。

4

您可以将[Obsolete("Use the property")]添加到该字段并通​​过编写#pragma warning disable 618来禁止该属性中的警告。

1

如果您不需要在存取做任何操作,使用auto-implemented property

我猜最有可能你想要做的业务,这就是为什么要确保您使用的属性,而不是支持字段

在这种情况下,考虑以下几点:。

  • 使用的命名惯例,如“_instanceName”,表示是私有成员场(你应该这样做无论如何...)
  • 当您感觉访问器中的操作很常见并且可重用时,请将其封装在一个类中。在遇到性能问题之前,不要担心矫枉过正。

我相信我会找到一个可能的解决方法,它是出奇的小。然而,这个'解决方案'可能有点太聪明了。也许我明天会做一些基准测试。现在的问题是,它也被用于所有使用它的地方,也许通过使用泛型可能会受到限制。

它利用事实lambdas always have the same backing method。通过将一个lambda传递给静态构造函数,静态对象可以跟踪这个唯一的“范围”并将变量链接到它。关于这个实现的更多细节can be found here

用法:

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)); 
} 

类:

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>; 
    } 
} 

这个话题can be found on Programmers.SE更广泛的讨论。