简体   繁体   English

在不可变接口上公开可变接口的最佳方法是什么?

[英]What's the best way expose a mutable interface over an immutable one?

I wonder what's the best practice in C# regarding mutable / immutable interfaces.我想知道 C# 关于可变/不可变接口的最佳实践是什么。

I like to work against interfaces only instead of the real objects;我喜欢只针对接口而不是真实对象; remove dependencies and allow for easier testing.删除依赖项并允许更轻松的测试。

I also usually expose interface that are read-only, which lower errors.我通常还公开只读接口,从而降低错误。 however this is creating a problem in the actual code when I need to change things on the instance of the object.但是,当我需要更改 object 实例上的内容时,这会在实际代码中产生问题。

Here's what I'm trying to do这就是我想要做的

public interface ISomething
{
    string Name { get; }   
}

public interface IMutableSomething : ISomething
{
    string Name { get; set; }   
}

...

public class ConsumerClass
{
   //Note that I'm working against the interface, not the implementation
   public void DoSomethingOnName(ISomething o)
   {
       var mutableO = (IMutableSomething) o;
       mutableO.Name = "blah";
   }
}

Working this way allows me to easily test ConsumerClass and break any dependency between the ISomething and it's implementation以这种方式工作使我能够轻松测试 ConsumerClass 并打破 ISomething 与其实现之间的任何依赖关系

I know that I could cast the interface to the implementation but this would introduce a dependency on the real implementation.我知道我可以将接口转换为实现,但这会引入对实际实现的依赖。

I could do something like below but I find it ugly and annoying我可以做类似下面的事情,但我觉得它丑陋和烦人

public interface IMutableSomething : ISomething
{
    void SetName(string newName)   
}

or

public interface IMutableSomething // No inheritance, implementation impl. 2 interfaces
{
    string Name { get; set; }
}

Thanks,谢谢,

Eric G.埃里克·G。

This isn't really the proper use of an interface;这并不是真正正确使用接口。 the interface is so that you don't care what implementation is, you simply use the defined properties and methods.接口使您不必关心实现是什么,您只需使用定义的属性和方法。 If you need to 'set' something that has a get only interface, you should not be passing the interface as a parameter.如果您需要“设置”具有仅获取接口的东西,则不应将该接口作为参数传递。

In this kind of situation, if you MUST go with an interface, define a set method on your interface (or implement the property differently)在这种情况下,如果您必须使用接口 go,请在您的接口上定义一个 set 方法(或以不同的方式实现该属性)

public interface ISomething
{
    string Name { get; set;}
    void SetName(string newValue);
}

// Choose one of these methods to implement; both is overkill
public class SomethingElse : ISomething
{
     protected string _internalThing = string.Empty;

     public string Name
     {
         get { return _internalThing; }
         set { throw new InvalidOperationException(); }
     }

     public void SetName(string newValue)
     {
         throw new InvalidOperationException();
     }
}

And then simply have the immutable interfaces do nothing with the value (or throw an exception).然后简单地让不可变接口对值不做任何事情(或抛出异常)。

I think your interfaces are fine, but in your consumer code it should look like this:我认为你的接口很好,但在你的消费者代码中它应该是这样的:

public class ConsumerClass{   
  // Just take IMutableSomething
  public void DoSomethingOnName(IMutableSomething o)   {       
    o.Name = "blah"; 
  }
}

The method call is a contract, and as others have said you need to specify the most general type that your ConsumerClass can actually use.方法调用是一种契约,正如其他人所说,您需要指定您的ConsumerClass实际可以使用的最通用类型。 You might want to read up on Liskov substitution principle: http://en.wikipedia.org/wiki/Liskov_substitution_principle .您可能想阅读 Liskov 替换原则: http://en.wikipedia.org/wiki/Liskov_substitution_principle

In this case, while IMutableSomething can substitute for ISomething, the inverse is not true.在这种情况下,虽然 IMutableSomething 可以替代 ISomething,但反之则不成立。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从外部代码的角度来看,可变结构是不可变的呢? - What about a mutable struct that's immutable from the standpoint of external code? 公开列表的最佳方式是什么<T>作为只读? - What is the best way to expose a List<T> as readonly? 在 C# 中向其他人提供接口定义的最佳方式是什么? - What's the best way to provide an interface definition to others in C#? 什么是判断鼠标是否在表单上方的最佳方法? - What's the best way to tell if the mouse is over a form or not? 在代码的整个生命周期中处理异常的最佳方法是什么? - What's the best way to handle exceptions over the lifetime of your code? 这个界面的最佳名称是什么? - What's the best name for this interface? 跨API传递不可变集合的最佳模式是什么? - What's the best pattern for passing Immutable Collections across APIs 实施一维碰撞检测的最佳方法是什么? - What's the best way to implement one-dimensional collision detection? 将一项添加到 IEnumerable 的最佳方法是什么<T> ? - What's the Best Way to Add One Item to an IEnumerable<T>? 以线程安全方式使用不可变类型不同于以相同方式使用可变类型的实际应用是什么? - What is a practical application of using an immutable type in a thread-safe way that differs from using a mutable type in the same way?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM