c # объект только для чтения

Есть ли способ вернуть экземпляр объекта только для чтения?

public class Person
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

public class SomeClass
{
    public SomeClass(Person manager)
    {
        if (manager == null)
            throw new ArgumentNullException("manager");

        _manager = manager;
    }

    private readonly Person _manager;
    public Person Manager
    {
        get { return _manager; } //How do I make it readonly period!
    }
}

Является ли единственный способ сделать это, возвращая Clone (), чтобы любые изменения были внесены в клон, а не в оригинал? Я знаю, что для массивов есть функция, которая возвращает массив только для чтения. О, и я знаю, что это ссылочный тип ... Кроме того, мне интересно, есть ли какая-то скрытая функция C # для блокировки записывающей части.

Я пытался придумать класс-оболочку Generic ReadOnly, но не смог выяснить, как получить свойства только для чтения, не делая дорогостоящих отражений и тому подобного.

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

22
задан m-y 23 August 2010 в 17:42
поделиться

6 ответов

Чтобы уберечь себя от создания дополнительного класса, вы можете заставить его реализовать его как интерфейс IPerson, который имеет только свойства только для чтения.

public interface IPerson
{
    string FirstName { get; }
    string LastName { get; }
}
public class Person:IPerson
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

public class SomeClass
{
public SomeClass(Person manager)
{
    if (manager == null)
        throw new ArgumentNullException("manager");

    _manager = manager;
}

private readonly Person _manager;
public IPerson Manager
{
    get { return _manager; } //How do I make it readonly period!
}
}
38
ответ дан 29 November 2019 в 04:06
поделиться

Такой функции нет - вы уже рассмотрели свои варианты.

Клонируйте его или создайте доступный только для чтения тип Person . Последний подход обычно предпочтительнее, потому что семантика более ясна: вызывающим абонентам очевидно, что они не должны (и не могут) изменять экземпляр.

2
ответ дан 29 November 2019 в 04:06
поделиться

Нет. Вы ищете что-то вроде const -ness в стиле C ++, а по различным причинам C # этого не имеет.

Однако анонимные типы действительно неизменяемы.

0
ответ дан 29 November 2019 в 04:06
поделиться

Вы можете заморозить объект (сделать его неизменным) при некоторых условиях с помощью Castle.DynamicProxy . Прочтите этот блог , сообщение , чтобы узнать подробности.

4
ответ дан 29 November 2019 в 04:06
поделиться

Анонимные объекты доступны только для чтения.

0
ответ дан 29 November 2019 в 04:06
поделиться

Невозможно сделать все свойства вашего объекта доступными только для чтения извне из класса. В приведенном выше примере вы не можете сделать свойства _manager доступными только для чтения, если вы не изменили свойства в классе Person, чтобы они были доступны только для чтения.

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

Или, если вы сделаете установщик свойств закрытым, то только код внутри Person может изменять значения свойств.

1
ответ дан 29 November 2019 в 04:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: