параметр метода может передавать объект по ссылке, но быть доступным только для чтения? - PullRequest
17 голосов
/ 08 августа 2010

C #: вы можете сделать так, чтобы параметр метода передавал объект по ссылке, но только для чтения?

например:

void MyMethod(int x, int y, read-only MyObject obj)

где obj - ссылка на объект, но этот объект нельзя изменить во время метода.

Может ли это быть достигнуто в C #?

Ответы [ 5 ]

17 голосов
/ 08 августа 2010

Нет.C # не имеет прямого аналога C ++ const (его собственный const - это нечто иное).Обычный шаблон C # для этого - передача интерфейса, такого как IEnumerable, который не допускает изменений.Вы также можете создать неизменную копию или оболочку.

6 голосов
/ 08 августа 2010

Если класс объекта, который вы передаете, был написан вами, то вам повезло.

Задайте себе вопрос: если бы в C # была функция const, какие операции с объектом я бы ожидал запретить через ссылку const на мой класс?

Затем определите interface, который исключает запрещенные операции.

Например:

class MyClass 
{
    public string GetSomething() { ... }

    public void Clobber() { ... }

    public int Thing { get { ... } set { ... } }
}

Соответствующий интерфейс "const" может быть:

interface IConstMyClass 
{
    public string GetSomething() { ... }

    public int Thing { get { ... } }
}

Теперь измените класс:

class MyClass : IConstMyClass
{

Теперь вы можете использовать IConstMyClass для обозначения const MyClass.

 void MyMethod(int x, int y, IConstMyClass obj)

Примечание: будут те, кто скажет вам, что этого недостаточно. Что если MyMethod возвращается к MyClass? Но игнорируйте их. В конечном счете, разработчик может использовать отражение, чтобы обойти любой аспект системы типов - посмотрите этот забавный пример .

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

3 голосов
/ 08 августа 2010

Это невозможно в C #.

Вы можете предотвратить это, передав неизменный объект.

0 голосов
/ 08 августа 2010

почему бы вам не сделать копию этого объекта и делать с ней что угодно, пока ваш obj остается неизменным.

Смотрите здесь, как клонировать ваш объект: Глубокое клонирование объектов

0 голосов
/ 08 августа 2010

Не существует механизма, который сделал бы это для вас.

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

...