如何在工厂中重载通用C#方法?

如何在工厂中重载通用C#方法?,c#,generics,overloading,factory,C#,Generics,Overloading,Factory,我想创建类似工厂的东西,但它不是工厂模式的实现 我有一个IServiceFactory接口: public interface IServiceFactory { TServiceInterface CreateService<TServiceInterface>(string url); } 公共接口IServiceFactory { TServiceInterface创建服务(字符串url); } 我想在我的实现中创建两个不同的服务,它们实现两个不同的接口。让我想想:

我想创建类似工厂的东西,但它不是工厂模式的实现

我有一个IServiceFactory接口:

public interface IServiceFactory
{
    TServiceInterface CreateService<TServiceInterface>(string url);
}
公共接口IServiceFactory
{
TServiceInterface创建服务(字符串url);
}
我想在我的实现中创建两个不同的服务,它们实现两个不同的接口。让我想想:

public class FirstService : IFirstService {}
public class SecondService : ISecondService {}

public class ServiceFactory : IServiceFactory
{
    public IFirstService CreateService<IFirstService>(string url)
    {
        // logic of creation
    }

    public ISecondService CreateService<ISecondService>(string url)
    {
        // Unforchantly, it's not an overloaded method
    }
}
公共类FirstService:IFirstService{}
公共类第二服务:ISecondService{}
公共类服务工厂:IServiceFactory
{
公共IFirstService CreateService(字符串url)
{
//创造逻辑
}
公共ISecondService CreateService(字符串url)
{
//不幸的是,它不是一个重载方法
}
}

如何以这种方式创建
SecondService
?我知道我的问题和代码示例很糟糕,这是一种不恰当的方法,但我想知道其他开发人员在这种情况下会做什么。谢谢

解决问题的最简单方法可能是避免完全重载工厂方法(虽然不是很“OO”)。检查泛型类型参数,创建适当的实例,并将其转换回正确的类型:

public class ServiceFactory : IServiceFactory {
    public TServiceType CreateService<TServiceType>(string url)
        {
            Type t = typeof(TServiceType);

            if (t == typeof(IFirstService))
                return (TServiceType) CreateFirstServiceInstance(url);

            if (t == typeof(ISecondService))
                return (TServiceType) CreateSecondServiceInstance(url);

            throw new InvalidOperationException("Unsupported service type");
        }
}
公共类服务工厂:IServiceFactory{
公共TServiceType CreateService(字符串url)
{
类型t=类型(t服务类型);
if(t==typeof(IFirstService))
返回(TServiceType)CreateFirstServiceInstance(url);
if(t==typeof(ISecondService))
返回(TServiceType)CreateSecondServiceInstance(url);
抛出新的InvalidOperationException(“不支持的服务类型”);
}
}

目前,
IServiceFactory
的合同规定可以创建任何服务。然而,您的具体实现只提供两种特定的服务。因此,您没有实现接口契约

我们如何解决这个问题?通过更改实现(以便可以创建任何服务)或更改契约(以便只能创建两个给定服务)。richzilla的回答为前者提供了一个例子,以下是后者的一个例子:

public interface IServiceFactory
{
    IFirstService CreateFirstService(string url);
    ISecondService CreateSecondService(string url);
}

public class ServiceFactory : IServiceFactory
{
    public IFirstService CreateFirstService(string url) { ... }
    public ISecondService CreateSecondService(string url) { ... }
}

你甚至不需要泛型。额外的好处:如果第一个和第二个服务需要不同的参数,您也可以支持它。

第一个服务和第二个服务应该扩展一个公共接口(例如,它们的接口扩展一个公共接口,比如ServiceInterface,或者它们直接从一些公共接口扩展,比如ServiceInterface) 对于具体创建,您可以将所需的具体类型(或字符串…)传递给工厂的create方法:

public interface IService {}
public interface IFirstService : IService {}
public interface ISecondService : IService {}
public class FirstService : IFirstService {}
public class SecondService : ISecondService {}

public class ServiceFactory : IServiceFactory {
    public IService CreateService<IService>(Type class, string url)
        {
            // logic of creation
            new class(url)
        }
}
公共接口IService{}
公共接口IFirstService:IService{}
公共接口ISecondService:IService{}
公共类FirstService:IFirstService{}
公共类第二服务:ISecondService{}
公共类服务工厂:IServiceFactory{
公共IService CreateService(类型类,字符串url)
{
//创造逻辑
新类(url)
}
}

我将使用一个通用的IAnyService空接口(一个纯空的“标记”接口),由IFirstService和ISecondService扩展。在我看来,这肯定不是最好的方法,我也对其他答案感兴趣!您应该能够像在接口中一样在类中使用它,使用泛型方法类型,
public T CreateService(string url)
,然后在函数内部可以检查T的类型,比如
if(T是IFirstService)
,但是为什么不单独使用工厂模式呢,我想它确实解决了你的问题。具有讽刺意味的是:C#中添加了泛型,因此我们需要更少的类型检查和类型转换。在这种情况下,通用解决方案实际上需要更多。。。