创建接口实例

nfp*_*lee 17 c# interface

我定义了以下接口:

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适用于哪个IAuditable
  • 我不能指定IAudit接口必须有一个构造函数接受IAuditable

我确信这是许多以前的设计模式,但我无法理解它.如果有人能告诉我这是如何实现的,我真的很感激.

Tri*_*dus 16

在代码中没有定义哪个IAudit适用于哪个IAuditable我无法指定IAudit接口必须具有一个构造函数,该构造函数具有IAuditable

你可以通过添加一个CreateAudit()函数来解决这两个问题IAuditable.然后你会得到一个IAudit创建IAuditable.作为奖励,如果你想存储IAuditIAuditable(或反之亦然)的引用,以便你可以让它们彼此相关,那么实现类很容易做到这一点.例如,您还可以添加GetAuditable()IAudit获取IAuditable它.

简单的实现看起来像这样(在实现IAuditable的类上):

public IAudit CreateAudit()
{
    UserAudit u = new UserAudit(UserName);
    return u;
}
Run Code Online (Sandbox Code Playgroud)

  • +1 正是我要发布的答案,但您似乎“真的”更快地理解了这个问题。 (2认同)

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的构造函数

正确,你不能.看到这里.您需要在实现者上创建这样的构造函数.


Mat*_*zer 5

一种方法是使用泛型。

一旦您拥有实现 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 对象的实例。


dee*_*ee1 5

显然你不能创建一个接口的实例,但如果你真的想创建一个传入类的实例,你可以这样做:

IAuditable j = ((IAuditable)Activator.CreateInstance(myObject.GetType()));
Run Code Online (Sandbox Code Playgroud)

您需要知道要构造哪个具体类,在您的示例中,唯一的选择是 myObject。

或者,您可以研究称为“依赖注入”的东西,它允许您指定将哪种类型的具体类“注入”到在构造函数或字段中调用接口的参数中。我不确定你的总体设计,所以这可能是适用的。在依赖注入中,您可以在代码中声明 IAuditables 应该使用 UserAudit 创建,尽管比简单地调用“new IAuditable”要多一些连接