Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.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/9/csharp-4.0/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#_Oop_Interface - Fatal编程技术网

C# 你会考虑改变接口或使用适配器吗?

C# 你会考虑改变接口或使用适配器吗?,c#,oop,interface,C#,Oop,Interface,我有一个接口,它返回一个类型的枚举 public interface IMapper { IEnumerable<IContract> Get(params object[] objects); } 我们感兴趣的代码行是注释后面的内容,因为我不喜欢只返回一个对象并将其称为列表Get()方法还可用于返回正确的列表,这恰好返回最多1个对象。 将单个对象作为列表返回是否合理,或者是否有更好的实现方法?这是一种折衷。目标是适合客户期望的类型。折衷是1)拥有一个额外的类和2)强制更改

我有一个接口,它返回一个类型的枚举

public interface IMapper
{
    IEnumerable<IContract> Get(params object[] objects);
}
我们感兴趣的代码行是注释后面的内容,因为我不喜欢只返回一个对象并将其称为列表Get()方法还可用于返回正确的列表,这恰好返回最多1个对象。


将单个对象作为列表返回是否合理,或者是否有更好的实现方法?

这是一种折衷。目标是适合客户期望的类型。折衷是1)拥有一个额外的类和2)强制更改现有类型

1)的优点是,现有类型保持不变(假设它目前与现有类型一样最有意义,返回一个IContract);1)的缺点是它需要更多的代码和更多的依赖项

2)的优点是代码大小和依赖项数量保持较低;2)的缺点是,纯粹为了满足客户的期望,通过更改类型以返回始终包含单个元素的列表,您颠覆了项目的类型设计

在强类型语言中,类型系统旨在帮助程序员。更大的详细性购买了类型系统的好处,而破坏该系统对减少详细性没有多大帮助,但却失去了该类型系统的好处。因此,我将使用带有适配器的强类型语言来解决这个问题,而不是通过更改接口


换句话说,用最小意外的原则解决问题()。如果项目中的另一个程序员(或者您自己,在几个月后)通常希望EscalationMapper的实例返回唯一的IContract,因此看到它返回IEnumerable会感到惊讶,那么请使用适配器()。相反,如果他们惊讶地看到它返回单个项,那么就更改接口

我同意@Abion47和@chrylis comments-0或1 items对于项目集合是完全有效的

但是-如果您不同意,并且仍然想要一种没有
IEnumerable
语义的方法来表达单个元素,那么可以使用一个方法重载
Get
,该方法接受单个对象并返回单个IContract。这将优先于params[]重载,因为
object
params[]object
更适合单个输入

这看起来像:

public interface IMapper
{
    IContract Get(object input);
    IEnumerable<IContract> Get(params object[] input);
}
我必须提醒大家,这样做感觉很奇怪,我认为这会在界面中引入不诚实。我还认为,有很大的潜力打破任何现有的代码,也调用了一个单一的输入接口

至于替换
对象
,您始终可以添加一些标记接口,如
icontracintput
,并将其传递到
Get
,而不是
对象

public interface IContractInput { /* Intentionally empty */ }
然后,用
icontracintput
标记任何输入类:

public class SomeInput : IContractInput { /* implementation.. */ }

这样,这些方法可以是强类型的,采用
icontracintput
而不是泛型的
对象
类型。

正如我在评论中所说的,您的代码在设计方面没有任何错误。即使调用
Get
的特定位置保证在返回的列表中最多返回一个项目,但这并不意味着在调用
IMapper.Get
的其他任何地方都保证返回

但是,如果您真的想简化它,使它返回单个对象而不是一个长度的列表,我也不建议更改接口以使用其他方法。这将破坏所有实现
IMapper
的类,并迫使您实现该新方法,即使在新方法无法添加任何有用内容的地方也是如此。如果其他人出于自己的目的使用您的代码,这将是一个特别大的问题,因为这将迫使他们也执行重写

但是,您可以做的一件事是将新方法声明为扩展方法:

public static class IMapperExtensions
{
    public static IContract GetSingle(this IMapper mapper, params object[] objects)
    {
        return mapper.Get(objects).FirstOrDefault();
    }
}
那么你可以这样称呼它:

var escalation = escalationMapper.GetSingle(trackingGroupCode);

这将在不破坏任何现有接口实现的情况下为您提供所需的功能。

如果它与Java无关,则不要将其标记为Java。这是C#代码,因此Java开发人员不会有太大帮助。了解,但有一个大型Java社区,这与接口有关,而不是底层编程语言。根据您的问题,只返回单个对象的列表是可以的,因为您的
Get
方法可以返回列表中的多个对象。如果你能保证它只会返回一个,那么你可以考虑改变它。你为什么觉得可笑?对于不确定的对象集合,0和1是完全有效的大小。很抱歉,代码上面的注释有点不合适。根据实现了多少其他位置
IMapper
,向接口添加其他方法可能不可行。对于其他方正在使用的库,尤其如此-添加另一个方法将强制每个实现类实现该方法,这将破坏兼容性并强制重写。我还想指出,在OP的示例中,
Get
的输入仍然是对象的集合,不是单个对象,因此更改方法以接受单个对象也会更改行为。还值得一提的是,从这个意义上讲,返回的单个对象参数和单个
IContract
对象基本上是一种过于冗长的强制转换方法。@Abion47您在破坏兼容性方面有很多优点。这不是我考虑过的,并且增加了我对引入这样的东西的担忧。但是,我们无法从原始示例中真正看出传递给
Get
的是什么,因为
public static class IMapperExtensions
{
    public static IContract GetSingle(this IMapper mapper, params object[] objects)
    {
        return mapper.Get(objects).FirstOrDefault();
    }
}
var escalation = escalationMapper.GetSingle(trackingGroupCode);