将类强制转换为实现接口

时间:2014-04-03 07:53:39

标签: c# interface

我有一个实现两个接口的类:

public class MyService : IServiceA, IServiceB

接口IServiceAIServiceB完全相同,但当MyService被实例化为每个接口时,一组不同的值充当MyService&# 39; s参数被加载到内存中:

public static string ServiceIdentifier;
IServiceA myService = new MyService(); // ServiceIdentifier should equal to: "A"
IServiceB myService = new MyService(); // ServiceIdentifier should equal to: "B"

到目前为止我已尝试过:

public class MyService
{
   public MyService()
   {
      if (this is IServiceA)
      {
        ServiceIdentifier = "A"
      }
      if (this is IServiceB)
      {
        ServiceIdentifier = "B"
      }
   }
}

但这似乎不起作用,因为在两种情况下它都返回:" A",我想因为MyService实现了两个接口所以第一个if参数在Test()中永远都是真的。

如何处理这种情况而不必依赖注入等?

Edit1 :我试图解决的问题是,许多全局参数必须具有不同的值,我希望将其依赖于MyService实例化的方式,无需始终将此信息注入其构造函数。

3 个答案:

答案 0 :(得分:1)

不清楚你要做什么,但看一下显式接口实现。

示例实施:

interface IServiceA
{
    void DoSomething();
}
interface IServiceB
{
    void DoSomething();
}
class MyService : IServiceA, IServiceB
{
    void DoSomething(string parameter)
    {
        Console.WriteLine("I'm " + parameter);
    }

    void IServiceA.DoSomething()
    {
        DoSomething("service A");
    }

    void IServiceB.DoSomething()
    {
        DoSomething("service B");
    }
}

<强>测试

void Main()
{
    var service = new MyService();

    IServiceA serviceA = service;
    serviceA.DoSomething();

    IServiceB serviceB = service;
    serviceB.DoSomething();
}

<强>输出:

  

我服务A
     我是服务B

也许您应该解释一下您的实际问题是什么,以便找到更好的解决方案。

答案 1 :(得分:1)

正如塞缪尔所说,你无法实例化一个界面。您可以做的是声明接口类型的变量,如:

IServiceA myService;

您可以为其分配实现该接口的任何类型的对象。当你然后分配这样的变量时(注意你的代码中没有'new'关键字):

IServiceA myService = new MyService();

您将myService设置为MyService类型(这很好,因为MyService实现了IServiceA)。

但是,MyService的构造函数不知道要为其分配实例的变量类型,因此没有(合理的)方法可以使用构造函数来分配给这样的属性。

事实上,如果IServiceA和IServiceB相同,那么无论如何你都会遇到一些问题。假设他们都声明了一个属性:

bool Test { get; set; }

然后在MyService或任何其他实现两个接口的类中,您需要将此属性称为IServiceA.TestIServiceB.Test - 我确定不是什么你想做什么。

我确信有更好的方法来做你想要达到的目标,但如果你能解释一下它背后的动机,那么我们可以尝试提供帮助会更有帮助。

修改

我想猜测你的目标,但看看这个。假设我们定义了一个单独的接口:

public interface IMyService
{
    string Name { get; }
}

和两个班级:

public class MyServiceA : IMyService
{
    public string Name
    {
        get
        {
            return "A";
        }
    }
}

public class MyServiceB : IMyService
{
    public string Name
    {
        get
        {
            return "B";
        }
    }
}

然后我们可以写一个这样的程序:

private static void Main(string[] args)
{
    IMyService testService;

    testService = new MyServiceA();
    Console.WriteLine(testService.Name);   // prints 'A'

    testService = new MyServiceB();
    Console.WriteLine(testService.Name);   // prints 'B'

    Console.ReadLine();
}

因此,局部变量testService已声明为IMyService类型,但可以为其指定类型为MyServiceAMyServiceB的对象(因为它们都实现了接口)。然后,您可以在不知道该对象的确切类型的情况下调用接口属性Name,如此示例所示,并且您将根据{{1的实际类型返回'A'或'B' }}

我希望这很清楚?

编辑2 (在对问题进行编辑之后):

您希望MyService具有不同的“状态”,具体取决于它实例化的方式,但您不希望将此信息传递给构造函数?那么 你希望MyService知道它应该做什么?

当然,您不必传递构造函数中的所有信息。您可以像这样定义testService类:

MyService

然后编写你的程序:

 public class MyService
 {
     public MyService(string letter)
     {
         if (letter == "A")
         {
             this.Name = "Service A";
             // Set other property values for service A
         }
         else if (letter == "B")
         {
             this.Name = "Service B";
             // Set other property values for service B
         }
         else
         {
             throw new NotImplementedException();
         }
     }

     public string Name { get; set; }
 }

因此,通过将一个字符的字符串传递给构造函数(并且有更好的方法,这只是一个示例/概念证明),您可以在没有界面的情况下实现您需要做的事情。

答案 2 :(得分:1)

如果将类定义为实现两个接口,那么该类的每个实例都将实现两个接口。您不能通过将其引用分配给IServiceA或IServiceB类型的变量来改变该类的实现。如果您有一个IServiceA类型的变量,则只是将您可以在底层对象中访问的功能/属性限制为定义为IServiceA的集合。

目前还不清楚你想要在这里实现什么,但也许你根本不需要使用接口。如果您只是使用一个属性来构造MyService对象,该属性说明它是什么类型的服务并将其作为私有成员变量保存在构造函数中,那么您可以稍后通过对象生命中的readonly属性访问该成员变量如你所愿。