Ограничение области действия члена класса за пределами частного - PullRequest
3 голосов
/ 13 февраля 2011

Мне было интересно, есть ли способ ограничить доступ члена класса специально для получения / установки реализаций в c #, чтобы уменьшить вероятность случайного доступа к ним напрямую. Что-то вроде private, но позволяет только получить / установить доступ к нему, я думал, что могу обернуть каждую переменную в свой класс, но это выглядит излишним из-за ограничения, которое я ищу. Спасибо

Ответы [ 4 ]

4 голосов
/ 13 февраля 2011

Вы можете добавить [Obsolete("Use the property")] в поле и подавить предупреждение в свойстве, написав #pragma warning disable 618.

3 голосов
/ 13 февраля 2011

Нет, к сожалению, нет.Я предполагаю, что вы захотите что-то вроде этого:

// 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 голосов
/ 13 февраля 2011

Это невозможно. Единственными модификаторами доступа являются private, internal, protected, protected internal и public, и ни один из них не отвечает требованиям.

Однако, если вы используете авто-свойство, то, конечно, вы можете получить к нему доступ только через get и set.

1 голос
/ 13 февраля 2011

Если вам не нужно выполнять какие-либо операции в средствах доступа, используйте автоматически реализованное свойство .

Я предполагаю, что, скорее всего, вы действительно хотите выполнять операции, и этопочему вы хотите убедиться, что вы используете свойство вместо поля поддержки.

В этом случае учтите следующее:

  • Используйте соглашение об именах, например "_instanceName", чтобы указать частноечленское поле.(Вы должны делать это в любом случае ...)
  • Когда вы чувствуете, что операции внутри ваших методов доступа являются общими и могут использоваться повторно, инкапсулируйте их в класс.Не беспокойтесь об избыточном количестве, пока не столкнетесь с проблемами с производительностью.

Полагаю, я мог бы найти возможный обходной путь, и он удивительно мал.Однако это «решение» может быть слишком умным.Возможно, я сделаю некоторые тесты завтра.Проблема в том, что в данный момент он также распространяется на все места, где он используется, возможно, с помощью дженериков это может быть ограничено.

В нем используется тот факт, что лямбды всегда имеют один и тот же метод поддержки .Передав лямбду статическому конструктору, статический объект может отслеживать эту уникальную область видимости и связывать с ней переменные.Подробнее об этой реализации можно найти здесь .

Использование:

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

Более общее обсуждениеэту тему можно найти на сайте Programmers.SE .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...