【问题标题】:Creating an Instance of an Interface创建接口实例
【发布时间】:2011-10-30 15:18:54
【问题描述】:

我定义了以下接口:

public interface IAudit {
    DateTime DateCreated { get; set; }
}

public interface IAuditable {
    IAudit Audit { get; set; }
}

IAuditable 接口说明我将为哪些类设置AuditIAudit 接口是该类的实际 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;
    }
}

现在给定一个对象IAuditable(上面的User),我希望能够通过输入IAuditable 对象来创建IAudit(上面的UserAdit)的实例进入构造函数。理想情况下,我会有类似的东西:

if (myObject is IAuditable) {
    var audit = new IAudit(myObject) { DateCreated = DateTime.UtcNow }; // This would create a UserAudit using the above example
}

但是我有很多问题:

  • 您不能创建接口的实例
  • 代码中没有定义哪个IAudit适用于哪个IAuditable
  • 我不能指定IAudit 接口必须有一个接受IAuditable 的构造函数

我确信这是许多人以前使用过的设计模式,但我无法理解它。如果有人能告诉我如何实现这一点,我将不胜感激。

【问题讨论】:

    标签: c# interface


    【解决方案1】:

    你不能创建接口的实例

    正确。你创建一个对象的实例实现一个接口:

    IAuditable myUser = new User();
    

    代码中没有定义哪个 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;
        }
    }
    

    我不能指定 IAudit 接口必须有一个接受 IAuditable 的构造函数

    没错,你不能。见here。您需要在实现者上创建这样的构造函数。

    【讨论】:

    • 有用的答案,对 OP 有用的信息,但仍然过于关注 c#/.net 的细节,无法得到我的支持……暂时。 Tridus 解决了 IMO 的真正 问题。不过,对于 OP 来说还是有用的信息。
    • 嗨,干杯,我已接受@Tridus 的回答,但我已使用您的部分建议来提供帮助。
    【解决方案2】:

    代码中没有定义哪个 IAudi 适用于哪个 可审计的 我无法指定 IAudi 接口必须有 采用 IAuditable 的构造函数

    您可以通过将CreateAudit() 函数添加到您的IAuditable 来修复这两个问题。然后你会得到一个从IAuditable 创建的IAudit。作为奖励,如果您想在IAuditable 中存储对IAudit 的引用(反之亦然),这样您就可以让它们相互关联,让一个实现类很容易做到这一点。例如,您还可以将 GetAuditable() 添加到 IAudit 以获取创建它的 IAuditable

    简单的实现如下所示(在实现 IAuditable 的类上):

    public IAudit CreateAudit()
    {
        UserAudit u = new UserAudit(UserName);
        return u;
    }
    

    【讨论】:

    • +1 正是我即将发布的答案,但您似乎really 更快地理解了这个问题。
    • @nfplee:您实际上是在询问更多设计问题,而您所寻求的答案并不在于 c# / .net 细节。这是你的答案,或者至少让你朝着正确的方向前进。
    • @Tridus:感谢您的回答,但现在是星期五下午很晚了,显然我的大脑已经炸了哈哈。如果我尝试说 ((IAuditable)myObject).CreateAudit()。它找不到 CreateAudit 方法。我相信我已经完成了你所说的一切。
    • @Tridus:请忽略我,我真的应该学会更多地构建并减少对智能感知的依赖哈哈。再次感谢您的帮助。
    【解决方案3】:

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

    IAuditable j = ((IAuditable)Activator.CreateInstance(myObject.GetType()));
    

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

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

    【讨论】:

      【解决方案4】:

      一种方法是使用泛型。

      一旦你有一个 T 类型,它实现了 I 接口并有一个公共的、无参数的构造函数,你就可以创建一个 T 的实例:

      public void Create<T> where T : IAudit, new()
      {
           T instance = new T();
           // TODO: Your logic using such T instance of IAudit implementation
      } 
      

      我不知道您的代码架构或目标,但您可以创建一个类似上述的工厂方法来创建 IAudi 对象的实例。

      【讨论】:

        【解决方案5】:

        您可以在作用域之外创建一个静态接口变量,然后在代码中使用它。

        static IRequestValidator ir;
        
        
        static void Main(string[] args)...
        

        【讨论】:

          【解决方案6】:

          如果您需要为接口创建实例,您可以创建一个名为 FactoryClass() 的公共类,其中包含所有接口方法。您可以使用以下代码:

          public class FactoryClass  //FactoryClass with Interface named "IINterface2"
          {
             public IInterface2 sample_display()   //sample_display() is a instance method for Interface
             {
                 IInterface2 inter_object = null;   //assigning NULL for the interface object
                 inter_object = new Class1();       //initialising the interface object to the class1()
                 return inter_object;   //returning the interface object
             }
          }
          

          在 Main() 类中添加以下代码:

          IInterface2 newinter; //creating object for interface in class main()
          FactoryClass factoryobj=new FactoryClass();  // creating object for factoryclass
          

          在构造函数中添加以下内容:

          newinter=factoryobj.sample_display() // initialisingg the interface object with the instance method of factoryobj of FACTORY CLASS.
          

          您可以使用以下代码调用 ffunction:

          newinter.display() //display() is the method in the interface.
          

          【讨论】:

            猜你喜欢
            • 2016-08-13
            • 2012-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-18
            • 2014-04-08
            相关资源
            最近更新 更多