Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控制对字段的读/写访问_C#_Design Patterns_Multiple Inheritance_Access Modifiers - Fatal编程技术网

C# 控制对字段的读/写访问

C# 控制对字段的读/写访问,c#,design-patterns,multiple-inheritance,access-modifiers,C#,Design Patterns,Multiple Inheritance,Access Modifiers,假设我们希望在接口模式中分离读写访问,如下所示 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 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; }
        }

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

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); }
    }
}
实现这一点并不容易。人们总是认为writeable.B应该继承两个基类writeable.A和ReadOnly.B,以避免重复代码

是否有推荐的设计模式可供使用?其目的是能够根据需求分别返回“只读访问”和“读写访问”对象(在编译时决定)。如果解决方案模式可以轻松添加更多的继承层,如类C、D


我知道多重继承的问题就出现在这里,而且在其他许多地方也有详细的讨论。但我的问题不在于“如何在不使用多重继承的情况下实现命名空间accesspattern中定义的接口”(尽管我想了解实现该接口的最佳方法),而是,我们如何分别定义类的只读/可写版本,并支持继承,而不让继承变得非常、非常、混乱

这里值得一提的是一个(混乱的)解决方案[请参阅下面的更好的实现]:

    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(); }
            }
        }
    }
}
更新:我认为这(以下)就是尤金所说的。我认为这种实现模式相当不错。通过只传递类的“writeProtected”视图,可以实现要求类的状态不会更改的算法,并且只使用“writeEnabled”视图,这意味着函数将/可能导致状态更改

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
        }
    }
}

您可以在服务级别而不是实体级别提供读/写访问。在这种情况下,您可以代码在处理读/写访问的服务周围生成一个包装器。
使用的模式:Decorator、依赖项注入

您可以在服务级别而不是实体级别提供读/写访问。在这种情况下,您可以代码在处理读/写访问的服务周围生成一个包装器。
使用的模式:Decorator、依赖注入

我知道这个线程已经有一年的历史了,但我想知道这样做是否有意义:

 interface ReadOnlyA
 {
    object A { get; }
 }

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

我知道这条线已经有一年的历史了,但我想知道这样做是否有意义:

 interface ReadOnlyA
 {
    object A { get; }
 }

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


你不能使用属性吗?您可以分别为每个
get
set
指定访问权限。我还记得列表中有一个AsReadOnly()。也许类似,但必须从可写类调用它。顺便说一句,类之间清晰分离的原因是什么?我们如何分别定义一个类的只读/可写版本,并同时支持继承而不会变得非常、非常、混乱?--您应该只创建两个接口(用于写和读访问)并从一个类继承它们,然后创建一个fabrica,在其中选择所需的类版本。Fabrica将通过所需的接口返回类的实例。仅此而已。@GMMan使用get set属性是否排除了xml序列化的使用?@GMMan分离读写访问的原因是因为有许多算法只需要读取类的值,而不需要进行更改。如果知道对象状态不会改变,则可以更有效地编写一些算法。例如,在多线程过程中,某些时候对锁的需求可能会被放弃。@Eugene,你能用一个例子进一步说明你的意思吗?谢谢。你不能使用属性吗?您可以分别为每个
get
set
指定访问权限。我还记得列表中有一个AsReadOnly()。也许类似,但必须从可写类调用它。顺便说一句,类之间清晰分离的原因是什么?我们如何分别定义一个类的只读/可写版本,并同时支持继承而不会变得非常、非常、混乱?--您应该只创建两个接口(用于写和读访问)并从一个类继承它们,然后创建一个fabrica,在其中选择所需的类版本。Fabrica将通过所需的接口返回类的实例。仅此而已。@GMMan使用get set属性是否排除了xml序列化的使用?@GMMan分离读写访问的原因是因为有许多算法只需要读取类的值,而不需要进行更改。如果知道对象状态不会改变,则可以更有效地编写一些算法。例如,在多线程过程中,某些时候对锁的需求可能会被放弃。@Eugene,你能用一个例子进一步说明你的意思吗?谢谢,谢谢你的建议。我认为你的评论只是一个建议,而不是答案。应该作为评论而不是回答吗?不管怎样,在你对帖子底部的评论之前,你觉得我写的代码怎么样?这是你的建议吗?如果没有,那么您能否提供一个示例代码来实现接口?谢谢,谢谢你的建议。我认为你的评论只是一个建议,而不是答案。应该作为评论而不是回答吗?不管怎样,在你对帖子底部的评论之前,你觉得我写的代码怎么样?这是你的建议吗?如果没有,那么您能否提供一个示例代码来实现接口?谢谢。你给某人一个伪装成
ReadOnlyA
WriteableA
实例。他们只是将它转换成可写lea,然后修改它。这要看情况而定。如果您实际控制写入访问,则WriteableA接口很可能是内部接口,并且只有ReadOnlyA接口是公共接口,因此没有强制转换。还有一种库场景,当
ReadOn