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

C# 从基类型到派生类型的工厂函数,c#,design-patterns,factory,C#,Design Patterns,Factory,我试图实现一个工厂函数,该函数接受一个基类型,并根据基类型是什么类型返回一个新的泛型类和一个派生类型,如下所示: public IStaffingEventValidator<T> GetValidator<T>(T staffingEvent) { switch (staffingEvent) { case HireEvent ev:

我试图实现一个工厂函数,该函数接受一个基类型,并根据基类型是什么类型返回一个新的泛型类和一个派生类型,如下所示:

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

                default:
                    return null;
            }
        }
公共IStaffingEventValidator GetValidator(T staffingEvent)
{
开关(staffingEvent)
{
案例HireEvent ev:
返回(IStaffingEventValidator)新的HireEventValidator();
违约:
返回null;
}
}
问题在于类型T是基本的
StaffingEvent
,而
HireEventValidator
是类型
istafingeventvalidator
,其中
HireEvent
StaffingEvent


我知道这不起作用,因为协方差和逆变,我的问题是我应该如何实现这样的东西?这是一个糟糕的设计吗?我有一个
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();
}
公共类StaffingEventBase,其中TValidator:istafingeventvalidator,new()
{
公共TValidator GetValidator()
{
返回新的TValidator();
}
}
公共类HireeEvent:StaffingEventBase
{
}
公共类HireEventValidator:IStaffingEventValidator
{
}
公共接口验证程序
{
}
公共静态void Main(字符串[]args)
{
var hireEvent=新的hireEvent();
//这里检索了正确的验证器。
var validator=hireEvent.GetValidator();
}
在这里工作:
我觉得它看起来不错。不过,我可以建议您使用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)
        {
            
        }
    }
类助手
{
公共StaffingEventValidator GetValidator(T staffingEvent)
{
开关(staffingEvent)
{
案例HireEvent ev:
返回新的员工验证人(ev);
//其他。。。
违约:
抛出新ArgumentException();
}
}
}
类staffing事件
{
}
HireeEvent类:StaffingEvent
{
}
类StaffingEventValidator
{
公共StaffingEventValidator(StaffingEvent ev)
{
}
}
类HireEventValidator:StaffingEventValidator
{
公共雇佣验证人(StaffingEvent):基础(ev)
{
}
}

那么,这是否意味着您有一个继承层次结构,如“StaffingEvent”、“SomeEvent:StaffingEvent”、“SomeOtherEvent:StaffingEvent”?以下内容:?将您的课堂设计纳入question@Fildor完全是:)尝试使用
StaffingEvent hireEvent=new hireEvent()我们不需要
Activator.CreateInstance
。添加
new()
约束并返回
new TValidator()
@N.Dogac是的,您是对的。我已经编辑了我的答案。谢谢,这是欺骗。OP显然有一个非通用的基础。这个例子就像说“抛弃基类”一样好。你不可能有,比如说一个
IEnumerable
,其中有不同的子对象。你会被混凝土卡住
IEnumerble
。也许你可以通过为StaffingEvents引入一个非通用接口来改进这一点?@Fildor是的。在这种情况下,我们可以有一个
事件
接口。因此,我们将使用IEnumerable。我给出的示例只是演示一个模拟代码。