我定义了以下接口:
public interface IAudit {
DateTime DateCreated { get; set; }
}
public interface IAuditable {
IAudit Audit { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
该IAuditable接口说,这班我将有一个Audit对.该IAudit接口是Audit该类的实际接口.例如,说我有以下实现:
public class User : IAuditable {
public string UserName { get; set; }
public UserAudit Audit { get; set; }
}
public class UserAudit : IAudit {
public string UserName { get; set; }
public DateTime DateCreated { get; set; }
public UserAdit(User user) {
UserName = user.UserName;
}
}
Run Code Online (Sandbox Code Playgroud)
现在给出一个IAuditable(User从上面)的对象,我希望能够IAudit通过将IAuditable对象输入构造函数来创建(上面的UserAdit).理想情况下,我有类似的东西:
if (myObject is IAuditable) {
var audit = new IAudit(myObject) { DateCreated = DateTime.UtcNow }; // This would create a UserAudit using the above example
}
Run Code Online (Sandbox Code Playgroud)
但是我有一堆问题:
IAudit适用于哪个IAuditableIAudit接口必须有一个构造函数接受IAuditable我确信这是许多以前的设计模式,但我无法理解它.如果有人能告诉我这是如何实现的,我真的很感激.
Tri*_*dus 16
在代码中没有定义哪个IAudit适用于哪个IAuditable我无法指定IAudit接口必须具有一个构造函数,该构造函数具有IAuditable
你可以通过添加一个CreateAudit()函数来解决这两个问题IAuditable.然后你会得到一个IAudit创建IAuditable.作为奖励,如果你想存储IAudit对IAuditable(或反之亦然)的引用,以便你可以让它们彼此相关,那么实现类很容易做到这一点.例如,您还可以添加GetAuditable()以IAudit获取IAuditable它.
简单的实现看起来像这样(在实现IAuditable的类上):
public IAudit CreateAudit()
{
UserAudit u = new UserAudit(UserName);
return u;
}
Run Code Online (Sandbox Code Playgroud)
Ode*_*ded 15
您无法创建接口的实例
正确.您创建实现接口的对象的实例:
IAuditable myUser = new User();
Run Code Online (Sandbox Code Playgroud)
在代码中没有定义哪个IAudit适用于哪个IAuditable
您不能只使用一个界面直接执行此操作.您需要重新考虑您的设计.
您可以在界面中使用开放泛型类型,并使用封闭类型实现它:
public interface IAudit<T> {
DateTime DateCreated { get; set; }
}
public class UserAudit : IAudit<User> {
public string UserName { get; set; }
public DateTime DateCreated { get; set; }
public UserAdit(User user) {
UserName = user.UserName;
}
}
Run Code Online (Sandbox Code Playgroud)
我不能指定IAudit接口必须有一个带有IAuditable的构造函数
正确,你不能.看到这里.您需要在实现者上创建这样的构造函数.
一种方法是使用泛型。
一旦您拥有实现 I 接口并具有公共无参数构造函数的 T 类型,您就可以创建 T 的实例:
public void Create<T>() where T : IAudit, new()
{
T instance = new T();
// TODO: Your logic here to use T instance of IAudit
}
Run Code Online (Sandbox Code Playgroud)
我不知道您的代码架构或目标,但您可以创建一个像上面这样的工厂方法来创建 IAudit 对象的实例。
显然你不能创建一个接口的实例,但如果你真的想创建一个传入类的实例,你可以这样做:
IAuditable j = ((IAuditable)Activator.CreateInstance(myObject.GetType()));
Run Code Online (Sandbox Code Playgroud)
您需要知道要构造哪个具体类,在您的示例中,唯一的选择是 myObject。
或者,您可以研究称为“依赖注入”的东西,它允许您指定将哪种类型的具体类“注入”到在构造函数或字段中调用接口的参数中。我不确定你的总体设计,所以这可能是适用的。在依赖注入中,您可以在代码中声明 IAuditables 应该使用 UserAudit 创建,尽管比简单地调用“new IAuditable”要多一些连接