【发布时间】:2017-05-10 23:10:10
【问题描述】:
假设我有以下界面:
public interface IMap<S, T>()
{
T Map(S source);
}
根据我使用的泛型类型参数,使用它的实现可能会变得很麻烦(即IMap<int, IEnumerable<SomeOtherType>>)
为了在本地简化事情,我希望能够声明一个显式命名的接口版本,例如:
public interface IMyMap : IMap<int, IEnumerable<SomeOtherType>> {}
不需要额外的方法;只是为了减少使用它的麻烦(特别是如果它归结为通过反射进行实例化)。
但是,如果我可以将具有完全相同类型参数的 IMap 的任何实现转换为特定命名的类型,我也更愿意。这不是 C++ Typedef,它非常适合我正在寻找的东西,这是 C#。
我可以编写一个接受任何形式的IMap<int, IEnumerable<SomeOtherType>> 并包装调用的实现。不过,这似乎最终会带来更多的麻烦而不是实现它的价值。
编辑:例如,我希望按照以下方式做一些事情:
public class SomeOtherType { }
public interface IMap<S, T> { T Map(S source); }
public interface IMyMap : IMap<int, IEnumerable<SomeOtherType>> {}
public class Main
{
public Main(IMap<int, IEnumerabel<SomeOtherType>> input)
{
IMyMap wrapped = input;
}
}
显然,这种请求严重依赖于IMyMap 没有比它实现的接口更多的定义。
tehDorf 提供的解决方案在我想要的范围内;但是,我也在寻找其他可能的解决方案,例如通过包装器工作:
public class MyMapWrapper : IMyMap
{
private IMap<int, IEnumerable<SomeOtherType>> wrapped;
public MyMapWrapper(IMap<int, IEnumerable<SomeOtherType>> wrapped)
{ this.wrapped = wrapped; }
public IEnumerable<SomeOtherType> Map(int source) { return wrapped.Map(source); }
}
还有其他不同的方法来做我正在寻找的事情吗?尤其是任何不属于单个文件的内容。
【问题讨论】:
-
我想我已经明白了。而且我认为您发布的代码正是您想要做的。您正在实现适配器模式。你有一个实现一个接口的类,你需要它来实现一个不同的接口。你所说的“包装器”是一个适配器。没有隐含的方法。
-
我感到困惑的原因是因为tehDorf建议和使用包装器是完全不相关的解决方案并且解决完全不同的问题。我不认为他们俩都可以解决同一个问题。
-
@ScottHannen 抱歉,我并不完全熟悉所有不同的模式名称。我看到它的方式是,在这个特定的实例中,我可以使用 using 别名将 IMyMap 定义为 IMap<...> 在使用并使用 IMyMap 实例的类的同一文件中 - 但是,别名仅存在于该文件中。或者,我可以将 IMyMap 定义为接口(项目范围的定义而不是本地文件),在上述类中使用它,并使用适配器模式来包装碰巧使用完全相同类型参数的 IMap 的任何非 IMyMap 实现.
标签: c# generics interface casting