我有一个有只读成员的课程
class A
{
public static readonly Student student = new Student("StudentName");
}
成员学生不是非常只读,我可以
A.student.Name = "Another Name";
学生是第三方课程,我无法改变。如何让它深入阅读?
答案 0 :(得分:4)
你不是。没有魔术关键词不仅会使引用成为不可变,而且会引用它所引用的对象。如果要使其成为真正不可变的,则需要使用不可变对象作为该字段的类型。你可以创建一个组合你的可变类型的包装类,而不公开暴露任何变异操作符,或者创建一个与你拥有的类型相当但是不可变的新类型,但是如果你公开那个现有的类型我们没有办法阻止某人改变它。
答案 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;
}
}
答案 2 :(得分:-4)
您可以继承Student类并从那里提供您自己的只读实现,确保每个可公开访问的setter都是最终的。当然,它仍然可以再次回复给学生,但为了您自己的开发目的,那么您可以确保它在本地“只读”。
或者您可以将学生课程包装在您自己的课程中,只允许访问获取者。
这里有一些示例代码来说明我所描述的方法,因为有些人似乎并不认为这是可能的......
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 = "";
这将允许再次访问,但鉴于你正在开发它,那么你可以确保它至少是“合理地”只读,只要有人不回来投下它,这将击败什么你希望通过这种发展来实现。
没有铸铁方法可以确保将来滥用子类技术,虽然它是一种非常合理的方法,只要它理解为什么要这样做,但是使用包装技术,那么你可以确保你的实现将不受滥用的影响。但是,如果将来更改包装的类,则必须相应地修改包装器。
另一种方法是简单地将自己的Student类实现编写为Immutable类。