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