简体   繁体   English

转换通用接口

[英]Casting generic interface

I have the following . 我有以下内容。

public interface IMyService<T>
   where T: BaseModelType
{
    Process(T input);
}        

public class BaseModelType
{
  ...some property
}

public class SomeClass : BaseModelType
{
   ...some properties
}

public ServiceImpl : IMyService<SomeClass>
{
    ...the properties
}

Then I have a unity container where i register all the implementations of the generic interface. 然后我有一个统一容器,我注册通用接口的所有实现。 I want to be able to use the unitycontainer's resolve method to get the interface, then do some work on it. 我希望能够使用unitycontainer的resolve方法获取接口,然后对其进行一些处理。 At the time when i want to use the Resolve method i have the type in runtime 当我想使用Resolve方法时,我在运行时具有类型

 new UnityContainer.Resolve(myTypeVar)

Can I somehow cast this to be 我可以以某种方式投这个

 IMyService<BaseModelType> value = new UnityContainer.Resolve(myTypeVar) //want to cast it here from object.

So that i can call the Process method that the interface defines. 这样我就可以调用接口定义的Process方法。

No, because IMyService<SomeClass> does not implement IMyService<BaseModelType> . 不,因为IMyService<SomeClass>没有实现IMyService<BaseModelType> If you look at the implementation of the Process method: 如果你看一下Process方法的实现:

public void Process(SomeClass input){...}

This clearly assumes that you're giving it a SomeClass . 这显然假设你给它一个SomeClass It should be able to safely access any members of SomeClass . 它应该能够安全地访问SomeClass任何成员。 But if you called this method with a BaseModelType as the parameter, that wouldn't work, would it? 但是如果你用BaseModelType作为参数调用这个方法, BaseModelType ,不是吗?

Assuming that you know at runtime that your input argument is going to be of the right type for the given generic IMyService<T> interface, you have two options: 假设你知道在你的运行时input参数将是正确的类型为给定的通用的IMyService<T>接口,你有两个选择:

  1. Invoke the generic method signature via reflection. 通过反射调用泛型方法签名。 A little slow, but effective. 有点慢,但有效。
  2. Add a non-generic parent interface for IMyService , which takes a BaseModelType . IMyService添加一个非泛型父接口,它接受一个BaseModelType In your service implementations, you can implement this method by casting the input to the expected type for that implementation. 在服务实现中,您可以通过将输入转换为该实现的预期类型来实现此方法。 This requires more code. 这需要更多代码。 But you could alleviate that somewhat by having a generic abstract base class that implements this method so the other implementations don't have to. 但是你可以通过使用一个实现这个方法的通用抽象基类来缓解这种情况,这样其他实现就不必这样了。

     void Main() { var s = (IMyService)new ServiceImpl(); s.Process(new SomeClass()); } public interface IMyService { void Process(BaseModelType input); } public interface IMyService<in T> : IMyService where T: BaseModelType { void Process(T input); } public class BaseModelType{} public class SomeClass : BaseModelType{} public abstract class ServiceBase<T> : IMyService<T> where T: BaseModelType { void IMyService.Process(BaseModelType input) { Process((T)input); } public abstract void Process(T input); } public class ServiceImpl : ServiceBase<SomeClass>{ public override void Process(SomeClass input){} } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM