是否可以创建实例并转换为通用接口类型?

时间:2015-03-11 14:02:44

标签: c# generics

我的项目中有以下界面和类

public interface IProcessor<T> : where T:IGenericData
{ 
   void Process(T data);
} 


public class CompanyADataProcessor : IProcessor<CompanyAData>
{
   void Process(CompanyAData Data);
}

CompanyAData实现IGenericData。

我想实现以下演员,是否有可能?          (IProcessor<IGenericData>)Activator.CreateInstance(typeof(CompanyADataProcessor));

更新

我认为我完全清楚为什么这不起作用。我想我需要改变我的设计才能解决我目前的问题。

基本上,我当前的问题是我们有一个数据文件处理器,每个客户端都有不同的数据模式,一些客户端数据需要额外清理,重新格式化等,然后保存到我们的数据库中,这就是我开始使用的原因之一单独的Processor类来处理特定的客户端数据。

当前逻辑首先从配置自定义部分启动所有处理器,因此,如果我们有一个新客户端有不同的数据,我们可以轻松创建一个新的处理器,将dll抛出到bin文件夹而无需重启应用程序。

 <Processors>
  <add  name="CompanyA" type="CompanyA.ThreeStepProcessor,CompanyA.Processor" outputPath="../../Output/CompanyA"/>
 .....
</Processors>

4 个答案:

答案 0 :(得分:4)

不,这是不可能的。如果是,则可以将该接口引用传递给其他代码,并且可以将IGenericData的任意实现的实例传递给CompanyADataProcessor类的Process()方法,当它显然只期望提供CompanyAData个实例时。

C#支持变体通用接口,但即使使用该语法也只允许在另一个方向进行转换,即从IProcessor<CompanyAData>转换为IProcessor<IGenericData>,而不是相反。鉴于您已经展示的界面,这是唯一可以保证类型安全的方向。

答案 1 :(得分:3)

彼得·邓尼奥的回答是正确的。你的方差是错误的。您的界面可以通过以下方式制作逆变(&#34; in&#34;):

public interface IProcessor<in T> ...

只会允许您所要求的相反转换。

语义原因是IProcessor<IGenericData>是可以处理任何 IGenericData的处理器,而IProcessor<CompanyAData>保证只处理CompanyAData 。 由于IProcessor<T>明确用于&#34; IProcessor<out T>&#34,因此无法制作T 协变(例如in) ;上下文。

所以(因为任何CompanyAData都是IGenericData):

  

IProcessor<IGenericData>IProcessor<CompanyAData>

但:

  

IProcessor<CompanyAData> IProcessor<IGenericData>

这就是逆变的全部。

答案 2 :(得分:1)

您的CompanyADataProcessorCompanyAData的恰当命名处理者。它需要CompanyAData作为输入并进行处理。如果将其强制转换为IProcessor<IGenericData>,则现在要求同一对象处理任何类通用数据。所以不,演员是不可能的。

答案 3 :(得分:0)

不,这是不可能的。你可以做的只是使用sta way接口

(IProcessor<CompanyAData>)Activator.CreateInstance(typeof(CompanyADataProcessor));

或使用方法创建一个声明类型

的实例
public T CreateInstance<T, TEntity>() 
    where T : IProcessor<TEntity>, new()
    where TEntity : IGenericData, new()
{
    return new T();
}

CreateInstance<CompanyADataProcessor, CompanyAData>();