如何让会员深入了解?

时间:2016-05-12 13:19:13

标签: c# constants readonly

我有一个有只读成员的课程

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

成员学生不是非常只读,我可以

A.student.Name = "Another Name";

学生是第三方课程,我无法改变。如何让它深入阅读?

3 个答案:

答案 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类。