控制对字段的读/写访问 [英] Controlling read/write access to fields

查看:102
本文介绍了控制对字段的读/写访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们要按如下所示的接口模式将读写访问权限分开.

Suppose that we would like to separate out the read and write access in an interface pattern as below.

namespace accesspattern
{
    namespace ReadOnly
    {
        public interface IA { double get_a(); }
    }
    namespace Writable
    {
        public interface IA : ReadOnly.IA { void set_a(double value); }
    }
}

这很容易实现:

namespace accesspattern
{
    namespace ReadOnly
    {
        public class A : IA
        {
            protected double a;
            public double get_a() { return a; }
        }
    }
    namespace Writable
    {
        public class A : ReadOnly.A, IA
        {
            public void set_a(double value) { base.a = value; }
        }

    }
}

假设我们需要另一个继承自A的类,因此我们继续为其定义一个接口:

Suppose that we need another class which inherits from A and so we go ahead and define an interface for it:

namespace accesspattern
{
    namespace ReadOnly
    {
        public interface IB : ReadOnly.IA { int get_b(); }

    }
    namespace Writable
    {
        public interface IB : ReadOnly.IB, Writable.IA { void set_b(int value); }
    }
}

实现此目标并非易事.人们总是觉得Writable.B应该继承自两个基类Writable.A和ReadOnly.B,以避免重复代码.

Implementing this is not so easy. One always feels that Writable.B should inherit from two base classes, Writable.A and ReadOnly.B, to avoid repeated code.

是否有建议使用的设计模式?目的是能够根据需要分别返回仅读访问"和读/写访问"对象(在编译时确定).如果解决方案模式可以轻松地添加更多的继承层(类C,D ...

Is there a recommended Design Pattern to use? The aim is to be able to return "read access only" and "read write access" objects separately (decided at compile time) depending on requirements. It would be nice if the solution pattern makes it easy to add more layers of inheritance, classes C, D...

我知道多重继承问题在这里浮出水面,并且已经在许多许多地方的其他地方进行了详尽的讨论.但是我的问题不是如何在不使用多重继承的情况下实现在命名空间访问模式内定义的接口"(尽管我想学习实现此目的的最佳方法),而是如何定义类的ReadOnly/Writable版本可以单独使用,并且还支持继承,而不会变得非常非常混乱?

I know that the issue of Multiple Inheritance crops up here and that it has been discussed at length elsewhere in many, many, places. But my question is not so much "How to implement the interfaces which are defined inside the namespace accesspattern without using multiple inheritance" (although I would like to learn the best way to do that) but rather, how can we define the ReadOnly/Writable versions of a class separately and also support inheritance without it getting very, very, messy?

对于这里值得的是一个(混乱的)解决方案[请参见下文,以获得更好的实现]:

For what it is worth here is one (messy) solution [see below for much a better implementation]:

    namespace accesspattern
    {
        namespace ReadOnly
        {
            public class A : IA
            {
                protected double a;
                public double get_a() { return a; }
            }
            public class B : IB
            {
                protected int b;
                public int get_b() { return b; }
            }
        }
        namespace Writable
        {
            public class A : ReadOnly.A, IA
            {
                public void set_a(double value) { base.a = value; }
            }
            public class B : ReadOnly.B, IB
            {
                private IA aObj;
                public double get_a() { return aObj.get_a(); }
                public void set_a(double value) { aObj.set_a(value); }
                public void set_b(int value) { base.b = value; }
                public B() { aObj = new A(); }
            }
        }
    }
}

更新:我认为这是Eugene在说的.我认为,这种实现方式非常好.通过仅传递类的"writeProtected"视图,可以实现一种算法,该算法要求类的状态不会改变,并且仅使用"writeEnabled"视图,在这种情况下,该函数将/将避免状态更改. /p>

Update: I think that this (below) is what Eugene is talking about. This implementation pattern is pretty good, I think. By only passing around "writeProtected" views of classes one can implement algorithms which require that the state of the class will not change and only use "writeEnabled" views where it is meant that the function will/could cause a change in state avoiding.

namespace access
{

    // usual usage is at least readable
    public interface IA { double get_a(); }
    public interface IB : IA { int get_b(); }

    // special usage is writable as well
    namespace writable
    {
        public interface IA : access.IA { void set_a(double value);  }
        public interface IB : access.IB, IA { void set_b(int value);}
    }

    // Implement the whole of A in one place
    public class A : writable.IA
    {
        private double a;
        public double get_a() { return a; }
        public void set_a(double value) { a = value; }
        public A() { }

        //support write-protection
        public static IA writeProtected() { return new A(); }
        public static writable.IA writable() { return new A(); }
    }
    // implement the whole of B in one place and now no issue with using A as a base class
    public class B : A, writable.IB
    {
        private int b;
        public double get_b() { return b; }
        public void set_b(int value) { b = value; }
        public B() : base() { }

        // support write protection 
        public static IB writeProtected() { return new B(); }
        public static writable.IB writable() { return new B(); }
    }

    public static class Test
    {
        static void doSomething(IA a)
        {
            // a is read-only
        }
        static void alterState(writable.IB b)
        {
            // b is writable
        }
        static void example()
        {
            // Write protected
            IA a = access.A.writeProtected();
            IB b = access.B.writeProtected();

            // write enabled
            writable.IA A = access.A.writable();
            writable.IB B = access.B.writable();

            Console.WriteLine(a.get_a());
            B.set_b(68);

            doSomething(A); // passed as writeprotected
            alterState(B); // passed as writable
        }
    }
}

推荐答案

我知道这个线程已经使用了一年,但是我想知道这样的事情是否有意义:

I know this thread is one year old, but I'm wondering if it would make sense to have something like this:

 interface ReadOnlyA
 {
    object A { get; }
 }

 interface WriteableA : ReadOnlyA
 {
   new object A {get; set;}
 }

这篇关于控制对字段的读/写访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆