从基类型到派生类型的工厂函数

Factory function from base type to derived type

我正在尝试实现一个工厂函数,它接受一个基类型和 returns 一个新的泛型 class,派生类型取决于基类型是什么类型,如下所示:

public IStaffingEventValidator<T> GetValidator<T>(T staffingEvent)
        {
            switch (staffingEvent)
            {
                case HireEvent ev:
                    return (IStaffingEventValidator<T>)new HireEventValidator();

                default:
                    return null;
            }
        }

问题是类型 T 是基数 StaffingEventHireEventValidator 是类型 IStaffingEventValidator<HireEvent>,其中 HireEventStaffingEvent

我知道这是行不通的,因为协变和逆变,我的问题是我应该如何实施这样的事情?这是一个糟糕的设计吗?我有一个 StaffingEvents 的列表,想为每个列表使用派生类型创建一个验证器。

我会改变它的架构。我之前也实现过类似的东西。描述起来有点复杂,直接给出示例代码

public class StaffingEventBase<TValidator> where TValidator : IStaffingEventValidator, new()
{
    public TValidator GetValidator()
    {
        return new TValidator();
    }
}

public class HireEvent : StaffingEventBase<HireEventValidator>
{

}

public class HireEventValidator : IStaffingEventValidator
{
}

public interface IStaffingEventValidator
{
}

public static void Main(string[] args)
{
    var hireEvent = new HireEvent();
    
    // Here retrieved the correct validator.
    var validator = hireEvent.GetValidator();
}

在这里工作: https://dotnetfiddle.net/VDqPGN

我觉得还不错。但是我可以建议您使用 OO 的另一种实现方式。

class Helper
    {
        public StaffingEventValidator GetValidator<T>(T staffingEvent)
        {
            switch (staffingEvent)
            {
                case HireEvent ev:
                    return new HireEventValidator(ev);
                // Others...
                default:
                    throw new ArgumentException();
            }
        }
    }

    class StaffingEvent
    {

    }

    class HireEvent : StaffingEvent
    {

    }

    class StaffingEventValidator
    {
        public StaffingEventValidator(StaffingEvent ev)
        {
            
        }
    }

    class HireEventValidator : StaffingEventValidator
    {
        public HireEventValidator(StaffingEvent ev) : base(ev)
        {
            
        }
    }