sta*_*ica 0

编辑:请注意,这个答案是在问题在编辑中完全改变之前给出的。因此,它现在指的是仅出现在最初所述的问题中的事物。我恳请您原谅所有的“悬空指针”。:-)


简短回答:

根据您发布的代码,我没有看到除了转换为IFoo<T>. 如果不这样做,编译器将发出警告(至少在我的机器上)。

更详细的答案:

您的代码实际上必须是这样吗?更具体地说,你首先需要有问题的演员阵容吗?

我假设您将或多或少地像这样调用您的工厂方法:

var stringFoo = FooFactory.CreateFoo<string>();
Run Code Online (Sandbox Code Playgroud)

您必须string显式提供模板参数(在本例中),因为它不能从任何方法参数派生(在本例中,因为实际上根本没有)。显然,工厂方法将返回一个IFoo<string>.

现在,由于您必须在运行时显式指定类型,因此您也可以编写:

var stringFoo = StringFoo.Create();
Run Code Online (Sandbox Code Playgroud)

因此内部有一个工厂方法StringFoo,就像这样,无条件地执行显而易见的操作:

public class StringFoo : IFoo<string>
{
    ...

    public static StringFoo Create()  // or alternatively, return an IFoo<string>
    {
        return new StringFoo();
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将此模式也应用于其他IFoo<T>实现,这将节省您内部的if链或块,使您的代码更容易,并消除强制转换的必要性(您所关心的)。switchFooFactory.CreateFoo<T>

不要误会我的意思,我知道支持多种对象类型的工厂方法在某些情况下很有用;但在你的情况下,它造成的麻烦似乎比其价值更多。


PS:您可能会发现某些 IoC 容器的某个方面很有趣。它们通常需要配置,这包括为抽象接口注册具体类型(即实现类)的过程;例如(此处使用Autofac):

var builder = new ContainerBuilder();
builder.RegisterType<StringFoo>().As<IFoo<string>>();
Run Code Online (Sandbox Code Playgroud)

然后,您可以请求抽象类型的对象实例:

using (var container = builder.Build())
{
    var stringFoo = container.Resolve<IFoo<string>>();
    ...
}
Run Code Online (Sandbox Code Playgroud)

方法Resolve是有趣的部分。您为它提供一个抽象类型,并使用注册的类型,它将返回一个类型的具体对象StringFoo。看看它,如果这对你来说听起来不太过分的话!:-)