限制类成员的范围超出私有

时间:2011-02-13 18:33:34

标签: c#

我想知道是否有办法专门访问类成员的访问权限来获取/设置c#中的实现,以减少我直接意外访问它们的机会。像private这样的东西只允许get / set访问它,我想我可以将每个变量包装在他们自己的类中,但这对于我正在寻找的限制来说似乎有些过分。感谢

4 个答案:

答案 0 :(得分:4)

您可以在字段中添加[Obsolete("Use the property")],并通过编写#pragma warning disable 618来取消警告。

答案 1 :(得分: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 :(得分:2)

这是不可能的。唯一的访问修饰符是privateinternalprotectedprotected internalpublic,而且没有一个适合该帐单。

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

答案 3 :(得分: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