等效接口之间的隐式转换

时间:2017-05-10 23:10:10

标签: c# generics interface casting

假设我有以下界面:

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); }
}

还有其他不同的方法来做我正在寻找的东西吗?特别是任何未降级为单个文件的内容。

2 个答案:

答案 0 :(得分:2)

您可以添加using alias directive(谢谢,itsme86):

using IMyMap = IMap<int, IEnumerable<SomeOtherType>>;

然后,在代码中您可以使用IMyMap,如下所示:

using System.Collections.Generic;
using IMyMap = SomeExample.IMap<int, System.Collections.Generic.IEnumerable<bool>>;

namespace SomeExample
{
    public interface IMap<T, S>
    {
        T Map(S source);
    }

    public class ExampleUsage
    {
        public IMyMap Foo { get; set; }

        public void SetFoo()
        {
            Foo = (IMyMap) new object();
            Foo = (IMap<int, IEnumerable<bool>>) new object(); // Same thing
        }
    }
}

但是,您必须将using alias指令添加到要使用它的任何代码文件中。

答案 1 :(得分:1)

你可以这样做:

public interface IMap<S, T>
{
    T Map(S source);
}

public class SomeClass { }
public class ThatClass { }

public interface IMapOfSomething : IMap<SomeClass, ThatClass> { }

public class Map : IMapOfSomething
{
    ThatClass IMap<SomeClass, ThatClass>.Map(SomeClass source)
    {
        throw new NotImplementedException();
    }
}

您可以将Map投射为IMapIMap<SomeClass, ThatClass> 您可以将IMap转换为IMap<SomeClass, ThatClass>

这部分不清楚:

  

如果我可以将具有完全相同类型参数的IMap的任何实现转换为特定命名的类型,我也更愿意。

如果课程没有实现IMap - 它恰好具有相同的属性和方法 - 那么不,你不能将其转换为IMap。这将违背语言。意图是你会故意实现一个接口。如果它是故意的,那么你会通过声明该类实现接口来表明。

想象一下,如果您可以在没有实际实现接口的情况下将某些内容转换为IMap ,可能会遇到麻烦,因为它具有相同的属性和方法。你可以改变那个类,使它不再是#34;看起来像&#34; IMap但您不会遇到任何编译错误。代码在运行时会失败。