Каковы различия между этими опциями для простого интерфейса с полем? - PullRequest
0 голосов
/ 07 ноября 2011

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

    private static IUnityContainer _container;
    public static IUnityContainer Container
    {
        get
        {
            return _container;
        }
        set
        {
            _container = value;
        }
    }

Я думаю, почему бы не один?

Я думаю, что ответ - что-то вроде "Вы не можете сломать инкапсуляцию" .. Это скорее реакция коленного рефлекса на обусловленность, или есть другие причины, тонкие или нет?

Ответы [ 2 ]

2 голосов
/ 07 ноября 2011

Ну, до тех пор, пока вы не захотите использовать отражение каким-то странным образом, например, GetType (). GetProperty ("Container" ...), недостатков нет.

Однако считается нечистым выставлять поле, свойство обычно чище с точки зрения пуристов.

FxCop предупредит вас, что это нехорошо, но недостатков нет.

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

public static IUnityContainer Container { get; set; }

Однако автоматические свойства работают только с версии 3.0 компилятора.

Возможный недостаток, который может возникнуть, если вы или кто-то передаете это поле byref в какой-либо функции, например, Interlocked.Exchange(ref MyClass.MyStaticField, null); Это больше не будет работать, если вы измените его со свойством в будущем, поэтому вы должны быть осторожны, не передавая это поле по ссылке. Если вы просто используете свойство с самого начала, у вас не может быть этой проблемы. Эта проблема не может возникнуть с полями static readonly, они не могут быть переданы по ссылке. Использование статических полей только для чтения довольно распространено.

Ситуация, когда поля абсолютно не должны использоваться вместо свойств, - это когда у вас есть класс, который наследует MarshalByRefObject, используемый для удаленного взаимодействия (RPC, удаленный вызов процедуры).

Здесь я публикую пример, и, как я уже сказал, это не ваш случай, так как проблема связана с полями экземпляра, а не со статическими полями.

public class MyClass :
    MarshalByRefObject
{
    public int MyValue;
}

class Program
{
    static void Main(string[] args)
    {
        var obj = new MyClass();

        // This will give you warning CS1690: Accessing a member on 'MyValue' may cause a runtime exception because it is a field of a marshal-by-reference class
        Console.WriteLine(obj.MyValue.ToString());
    }
}

Удаленный вызов процедуры работает только с методами и свойствами, поэтому компилятор выдает предупреждение, поскольку MarshalByRefObject может вызываться внутри другого AppDomain или другого процесса или другого компьютера, например, через TCP / IP.

0 голосов
/ 07 ноября 2011

Лично я думаю об этом так.Допустим, позже я хочу установить инвариант, что «контейнер» никогда не будет нулевым.Если оно определено как открытое поле, способ принудительного применения этого состоит в том, чтобы искать каждого клиента, который его использует, и помещать код для предотвращения его установки в нуль.Если у меня есть это свойство, то же самое может быть выполнено с помощью чего-то вроде:

private static IUnityContainer _container = new ContainerImpl();
public static IUnityContainer Container
{
    get
    {
        return _container;
    }
    set
    {
        _container = value ?? _container;
    }
}

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

Итак, я думаю, что это не просто реакция коленного рефлекса, а прагматичная и разумная, особенно перед лицом статического ключевого слова.Без инкапсуляции это буквально просто глобальная переменная.По крайней мере, инкапсуляция глобального состояния позволяет провайдеру иметь некоторое подобие контроля над ним, вместо того, чтобы утратить контроль над всем приложением и доверять / заставлять клиентов быть согласованными.Не повторяйся ".Любая общая логика, когда дело доходит до поля, обязательно будет повторяться повсюду.

...