【问题标题】:How to overload generic C# methods in Factory?如何在工厂中重载泛型 C# 方法?
【发布时间】:2017-05-26 09:05:14
【问题描述】:

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

我有一个 IServiceFactory 接口:

public interface IServiceFactory
{
    TServiceInterface CreateService<TServiceInterface>(string 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
    }
}

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

【问题讨论】:

  • 我将使用由 IFirstService 和 ISecondService 扩展的通用 IAnyService 空接口(一个普通的空“标记”接口)。在我看来,这当然不是最好的方法,我也对其他答案感兴趣!
  • 您应该能够在类中使用它,就像在接口中一样,使用泛型方法类型 public T CreateService&lt;T&gt;(string url) 然后在函数内部您可以检查 T 的类型,例如 if (T is IFirstService) 但是为什么不单独使用工厂模式,我猜它确实解决了你的问题。

标签: c# generics overloading factory


【解决方案1】:

解决问题的最简单方法可能是避免完全重载工厂方法(虽然不是很“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");
        }
}

【讨论】:

  • 具有讽刺意味的是:泛型已添加到 C# 中,因此我们需要 less 类型检查和类型转换。在这种情况下,通用解决方案实际上需要更多...
【解决方案2】:

目前IServiceFactory的合约规定可以创建any服务。但是,您的具体实现仅提供两种特定服务。因此,您没有实现接口协定。

我们如何解决这个问题?通过更改实现(以便可以创建任何服务)或更改合同(以便只能创建两个给定的服务)。 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) { ... }
}

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

【讨论】:

    【解决方案3】:

    FirstService 和 SeconService 应该扩展一个通用接口(例如,它们的接口扩展了一个通用接口,如 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)
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多