我有一个将约束作为基类的接口
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>;
}
}
}