Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.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

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#:接口继承getter/setter_C#_Design Patterns_Inheritance_Interface - Fatal编程技术网

C#:接口继承getter/setter

C#:接口继承getter/setter,c#,design-patterns,inheritance,interface,C#,Design Patterns,Inheritance,Interface,我有一组与特定可变对象紧密结合使用的接口 该对象的许多用户只需要能够从该对象读取值,然后只需要几个属性。为了避免名称空间污染(更简单的智能感知)和理解使用意图,我希望有一个小的基本接口,它只以只读方式公开一些“键”属性 但是,几乎所有的实现都支持完整的接口,其中包括可修改性 不幸的是,我在C#中遇到了表达这一概念的障碍: 我当然不想隐藏任何成员,所以这并不好 当然,我可以用方法很好地解决这个问题,但是什么是正确的选择呢?我希望保持“核心”接口尽可能小,即使拆分接口除了通信目的之外没有其他用途。对

我有一组与特定可变对象紧密结合使用的接口

该对象的许多用户只需要能够从该对象读取值,然后只需要几个属性。为了避免名称空间污染(更简单的智能感知)和理解使用意图,我希望有一个小的基本接口,它只以只读方式公开一些“键”属性

但是,几乎所有的实现都支持完整的接口,其中包括可修改性

不幸的是,我在C#中遇到了表达这一概念的障碍:

我当然不想隐藏任何成员,所以这并不好

当然,我可以用方法很好地解决这个问题,但是什么是正确的选择呢?我希望保持“核心”接口尽可能小,即使拆分接口除了通信目的之外没有其他用途。对于拆分接口,很明显哪些方法不会进行任何更新,并且它使编写代码更加清晰(更不用说还允许nice-n-simple静态单例存根,可以满足相当多的简单情况)

我希望避免任何抽象类之类的东西;他们使重新实施或快速单一用途填隙片变得更加复杂和难以探索


所以,隐藏在接口中的想法?

方法并没有那么乏味;我会选择这样的方式:

interface IBasicProps {
   int Priority { get; }
   string Name {get;}
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   new int Priority { get; set; }
   new string Name { get; set; }
   //... whatever
}
class Foo : IBasicPropsWriteable {
    public int Priority {get;set;}
    public string Name {get;set;}
/* optional
    int IBasicProps.Priority {get {return Priority;}}
    string IBasicProps.Name {get {return Name;}}
*/
}

如果您的目标是在允许读和写时使其更清晰,那么我将使用单独的getter和setter方法,而不是属性

interface IBasicProps {
   int GetPriority();
   string GetName();
   //... whatever
}

interface IBasicPropsWriteable:IBasicProps  {
   void SetPriority(int priority);
   void SetName(string name);
   //... whatever
}

一种方法是跳过接口的继承。制作一个只读接口和一个只读写接口,并根据需要实施:

interface IBasicPropsReadable {
   int Priority { get; }
   string Name { get; }
}

interface IBasicPropsWriteable  {
   int Priority { set; }
   string Name { set; }
}

class SomeClassReadWrite : IBasicPropsReadable, IBasicPropsWriteable {
    int Priority { get; set; }
    string Name { get; set; }
}

class SomeClassReadOnly : IBasicPropsReadable {
    int Priority { get; }
    string Name { get; }
}

您可以让接口不相关,只需让您的类实现这两个接口。在所有接口都只是定义了契约之后,契约不需要关联。在编码时,让可写的一个从另一个派生出来似乎只是一种优化,因此只需指定一个接口

public interface IBasicProps
{
   int Priority { get; }
   string Name {get;}
   //... whatever
}

public interface IBasicPropsWriteable
{
   int Priority { get; set; }
   string Name { get; set; }
   //... whatever
}

public class Foo : IBasicProps, IBasicPropsWriteable
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}
如果您确实需要优化,您可以创建另一个从这两者派生的接口,并让您的类实现它

public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable  { }

public class Foo : IBasicPropsAll
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}

IBasicprossall方法不起作用(非常好)<代码>((IBasicPropsAll)new Foo())。名称不明确,编译器不会接受它。这意味着你需要投普通票。是的。您只需要使用它来获得不必同时键入两个接口的“优化”。我不推荐。实际上,您不会使用它,而是将其转换为IBasicProps或iBasicPropsWrited,这不允许我表达“读/写对象”的一般概念。现在,我如何才能编写一个只接受读/写变体的方法呢?这不是选美比赛的赢家,但它看起来是一个相当安全的赌注,它会很好地工作……作为奖励,这实际上也适用于co/contrance;我的实际用例更像是
IBasicProps{/*…*/}IBasicPropsWriteable:IBasicProps{}
。在这里,接口拆分是必要的;中央管理器希望协方差将各种对象放在一个集合中,但每个对象的各个所有者都知道它包含的类型。您如何看待在派生接口中省略新属性的getter,如这里所建议的那样?虽然这可能是C#中最不糟糕的解决方案,但使用
new
修饰符仍然不令人满意,因为它意味着“存在同名的不相关属性,旧属性仍然存在,但需要更复杂的语法来通过
IBasicPropsWriteable
进行访问”。如果您可以使用额外的访问器扩展“相同”属性,那就太好了。(类相互继承也存在同样的问题。)在您的解决方案中,代码
静态void M(IBasicPropsWriteable x){var a=x.Name;var b=((IBasicProps)x.Name;}
正式读取两个不同的成员!
public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable  { }

public class Foo : IBasicPropsAll
{
   public int Priority { get; set; }
   public string Name { get; set; }

   // whatever
}