为什么接口需要强制转换?

时间:2014-02-27 18:36:25

标签: .net c#-4.0

我正在尝试针对某个接口创建一个实例,但它因转换错误而失败。

以下简单方案可以正常使用。

class Employee:IEmployee
{
  public Employee (int Id) {}
  public string Name {get;set;}
}

interface IEmployee
{
  string Name {get;set;}
}

//执行

IEmployee employee = new Employee(1)

我有更大的课程,同一场景无效。主要是他们只是更大的班级。我在下面得到了编译时错误:

Cannot implicitly convert type 'IDirector' to 'Director'.  An explicit conversion exists (are you missing a cast?)

我不得不使用以下类型的语法:

IDirector myDirector = (IDirector)new Director(directorId);

Director确实实现了IDirector。这些是单个对象,不列入单个对象。

如果我通过类构造函数传递接口并尝试将其分配给实现接口的类类型,它也不起作用:

private ClassB classb;

Public ClassA (IClassB classbInterfaceInstance)
{
  classb = classbInterfaceInstance;
}

知道为什么在某些情况下需要演员而不是其他人?

2 个答案:

答案 0 :(得分:0)

您无法将接口实例分配给其驱动类。有一个深刻的概念,但我用简单的例子来说明。

考虑这个接口和类代码:

interface IClassA 
{
   int MemOfA;
}

interface IClassB
{
   int MemOfB;
}

class MyClass : IClassA,IClassB
{
   int MemOfA;
   int MemOfB;
}

现在在一些代码块中我们定义了一个类MyClass的实例(考虑iIClassA是接口IClassA的实例):

MyClass a = iIClassA; // error !

为什么错误?

我们如何在IClassB中设置MyClass的成员?但是,如果MyClass再次实施IClassA,我们就无法做到!因为IClassA可能会继承多个接口。

答案 1 :(得分:0)

private ClassB classb;

Public ClassA (IClassB classbInterfaceInstance)
{
  classb = classbInterfaceInstance;
}

无法使此代码正常工作。请记住:ClassB实现了IClassB。所以ClassB总是IClassB。 但请考虑以下情况: 你有一个接口:IClassB。并且有两个类 - ClassB1和ClassB2。两者都实现了IClassB。

interface IClassB {}
class ClassB1 {}
class ClassB2 {}

IClassB foo = new ClassB2();
ClassB1 = foo; //this can not work. Because you are trying to cast ClassB2 to ClassB1

看看我的代码。这正是你在做的事情:

private ClassB classb;
//workaround 1)
private IClassB classb;

Public ClassA (/*workaround 2)*/ ClassB /*instaed of IClassB*/ classbInterfaceInstance)
{
  //remember that classbInterfaceInstance can be ClassB2, ClassB3, ... what ever. But you are casting it into ClassB.
  classb = classbInterfaceInstance;

  //possible workarounds:
  // 1) make the "classb" field of type "IClassB" (see above)
  // 2) change the type of the classbInterfaceInstance parameter to ClassB
  // 3) try to cast the parameter (see code below)

  //workaround 3)
  if(classbInterfaceInstance is ClassB)
  {
    classb = (ClassB)classbInterfaceInstance;
  }
}