2016-05-12 4 views
1

У меня есть класс, который имеет только для чтения членаКак сделать член глубоко читаемым?

class A 
{ 
    public static readonly Student student = new Student("StudentName"); 
} 

и студент-член не глубоко чтения, я могу

A.student.Name = "Another Name"; 

Студент класс третьей стороной, что я не могу изменить. Как сделать его глубоко читаемым?

+1

Сделать приватным и подвергать каждое свойство самостоятельно через свойства только для чтения. –

+0

«И ученик-член не глубоко читаем», хорошо, я понимаю, что английский не является вашим первым языком. Но что вы подразумеваете под «глубоко читаемым»? Не понятно. – TomTom

+2

@TomTom: он означает, что никто не сможет изменить имя учащегося (или другие свойства) позже. –

ответ

4

У вас нет. Не существует волшебного ключевого слова, которое сделает не только ссылку неизменной, но и объект, на который она ссылается неизменной. Вам нужно использовать неизменяемый объект как тип этого поля, если вы хотите сделать его действительно неизменным. Вы могли бы создать класс-оболочку, который будет составлять ваш изменяемый тип, без публичного обнародования любого из операторов мутаций или создать новый тип, сопоставимый с тем, который у вас есть, но который неизменен, но если вы обнаружите, что существующий тип из этого класс, вы ничего не можете сделать, чтобы остановить кого-то от его мутации.

-4

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

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

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Student student = new Student(); 
      student.Name = "Joe"; 

      StudentSubClass studentSubClassed = new StudentSubClass(); 
      studentSubClassed.Name = ""; // THIS LINE IS DISALLOWED FOR COMPILATION. 

      StudentWrapper studentWrapped = new StudentWrapper(student); 
      studentWrapped.Name = ""; // THIS LINE IS DISALLOWED FOR COMPILATION. 
     } 
    } 

    class Student 
    { 
     public string Name { get; set; } 
    } 

    class StudentSubClass : Student 
    { 
     public new string Name { get; private set; } 
    } 

    class StudentWrapper 
    { 
     private Student student; 

     public StudentWrapper(Student student) 
     { 
      this.student = student; 
     } 

     public string Name 
     { 
      get 
      { 
       return this.student.Name; 
      } 
     } 
    } 
} 

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

var newStudent = (Student)studentSubClassed; 
newStudent.Name = ""; 

И это позволило бы доступ снова, но, учитывая, что это ты, что это его разработку, то вы можете быть уверены, что это по крайней мере, «разумно» только для чтения при условии, кто не вернитесь и бросьте это, что приведет к победе над тем, что вы ho ping для достижения этой разработки.

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

Другой альтернативой было бы просто написать собственную реализацию класса Student в качестве класса Immutable.

+3

Вы не можете удалить операции с производным типом, только добавить их. – Servy

+0

Вы можете с классом обертки. Всегда есть круглые ограничения. – ManoDestra

+1

Обертка не происходит. –

0

Ваш Student класс должен иметь свой набор свойств private. Если у вас нет контроля над классом, создайте обертку, у которой есть только private сеттеры.

public class Student 
{ 
    public string Name { get; private set; } 

    public Student(string name) 
    { 
     Name = name; 
    } 
} 

Или обертка:

public class StudentWrapper 
{ 
    Student _student; 

    public string Name { get { return _student.Name; } } 

    public Student(Student student) 
    { 
     _student = student; 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^