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

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

например:

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

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

Можно ли это сделать на С#?

Ответы

Ответ 1

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

Ответ 2

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

Спросите себя: если у С# была функция 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

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

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

Ответ 4

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

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

Ответ 5

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

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