接口通用父子对象初始化



我有一个将约束作为基类的接口

abstract class BaseElement { };
interface IOperation <T>where T:BaseElement
{
    void Add (T field1);
}

为基类创建了一个子对象

class StudentDTO : BaseElement
{
    public int Id { get; set; }
};
class SubjectDTO : BaseElement
{
    public string Name { get; set; }
};

实现了 2 个具有 IOperation 接口的类

class Student : IOperation<StudentDTO>
{
    public void Add(StudentDTO field1)
    {
        Console.WriteLine("Child A" + field1.Id);
    }
}
class Subject : IOperation<SubjectDTO>
{     
    public void Add(SubjectDTO field1)
    {
        Console.WriteLine("Child B" + field1.Name);
    }
}

实现了工厂模式以返回 DTO 对象。

static class BLFactory
{
    public static IOperation<BaseElement> CreateObject(BaseElement baseObject)
    {
        if (baseObject.GetType().Name == "SubjectDTO")
        {
            return new StudentDTO() as IOperation<BaseElement>;
        }
        else
        {
            var temp = new SubjectDTO() as IOperation<BaseElement>;
            return temp;
            ////************ temp object returns null *************
        }
    }        
}

现在,当我使用 BLFactory 创建 DTO 对象时,我将其作为 NULL。不知道如何解决问题。任何建议如何解决此问题或正确的实施方式是什么。

好吧,首先StudentDTO根本没有实现IOperation; Student有,但StudentDTO没有。

即使你确实使用了Student那也行不通。 学生实施IOperation<StudentDTO>而不是IOperation<BaseElement>

仅仅因为StudentDTO可以隐式转换为BaseElement并不意味着IOperation<StudentDTO>可以隐式转换为IOperation<BaseElement>IOperation需要协变才能出现这种情况,但事实并非如此。

如果你愿意,你可以IOperation逆变,因为T只用作输入,但这会使你能够隐式地将IOperation<BaseElement>转换为IOperation<StudentDTO>,而不是相反。

根据as运算符的文档:

as 运算符类似于强制转换操作。但是,如果无法进行转换,返回null而不是引发异常。

由于StudentDTO不是从IOperation<...>继承的,SubjectDTO也不是从IOperation<...>继承的,因此由于操作as,您将temp变量中得到null

因为SubjectDTO不是IOperation<BaseElement>。 这是一个BaseElement.

也不是Subject - 它是一个不继承IOperation<BaseElement> IOperation<SubjectDTO>

似乎您的BLFactory基本上为每种类型返回了正确的"存储库",最好使用 Ninject 或 Unity 等 DI 框架以声明方式完成。

但是,如果要对其进行硬编码,则可以将其设置为通用BLFactory

static class BLFactory<U> where U:BaseElement
{
    public static IOperation<U> CreateObject()
    {
        if (typeof(U).Name == "SubjectDTO")
        {
            return new Student() as IOperation<U>;
        }
        else
        {
            return new Subject() as IOperation<U>;
        }
    }        
}

最新更新