web-dev-qa-db-fra.com

Créer une instance d'une interface

J'ai les interfaces suivantes définies:

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

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

L’interface IAuditable indique les classes pour lesquelles je vais avoir un Audit. L'interface IAudit est la Audit réelle pour cette classe. Par exemple, disons que j'ai les implémentations suivantes:

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;
    }
}

Maintenant, étant donné un objet qui est IAuditable (User d'en haut), j'aimerais pouvoir créer une intance de IAudit (UserAdit d'en haut) en introduisant l'objet IAuditable dans le constructeur. Idéalement, j'aurais quelque chose comme:

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

Cependant, j'ai un tas de problèmes:

  • Vous ne pouvez pas créer une instance d'une interface
  • Aucun endroit dans le code ne définit-il quelle IAudit s'applique à quelle IAuditable
  • Je ne peux pas spécifier que l'interface IAudit doit avoir un constructeur qui prend une IAuditable

Je suis sûr que c'est un motif de conception que beaucoup ont eu auparavant mais je n'arrive pas à comprendre. J'apprécierais vraiment si quelqu'un pouvait me montrer comment cela peut être réalisé.

15
nfplee

Aucun endroit dans le code ne définit-il quel IAudit s'applique à quel IAuditable Je ne peux pas spécifier que l'interface IAudit doit avoir un constructeur qui prend une IAuditable

Vous pouvez résoudre ces deux problèmes en ajoutant une fonction CreateAudit() à votre IAuditable. Vous obtiendrez alors une IAudit créée à partir de la IAuditable. En prime, si vous souhaitez stocker une référence à la variable IAudit dans la variable IAuditable (ou l'inverse) afin que vous puissiez les relier les unes aux autres, il est assez facile de faire appel à une classe d'implémentation. Vous pouvez également ajouter GetAuditable() à IAudit pour obtenir la IAuditable à partir de laquelle elle a été créée, par exemple.

Une implémentation simple ressemblerait à ceci (sur une classe implémentant IAuditable):

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

Vous ne pouvez pas créer une instance d'une interface

Correct. Vous créez une instance d'objet implémentant une interface:

IAuditable myUser = new User();

Aucun endroit dans le code ne définit-il quel IAudit s'applique à quel IAuditable

Vous ne pouvez pas le faire directement avec une seule interface. Vous devrez repenser votre conception.

Vous pouvez utiliser un type générique ouvert dans l'interface et l'implémenter avec des types fermés:

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;
    }
}

Je ne peux pas spécifier que l'interface IAudit doit avoir un constructeur qui prend un IAuditable

Correct, vous ne pouvez pas. Voir ici . Vous devez créer un tel constructeur sur les implémenteurs.

14
Oded

Une façon serait d'utiliser des génériques.

Une fois que vous avez un type T qui implémente I interface et a un constructeur public, sans paramètre, vous pouvez créer une instance de T:

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

Je ne connais pas votre architecture de code ni votre objectif, mais vous pouvez créer une méthode fabrique comme celle ci-dessus pour créer des instances d'objets IAudit.

4
Matías Fidemraizer

Évidemment, vous ne pouvez pas créer une instance d'interface, mais si vous essayez réellement de créer une instance de la classe passée, vous pouvez faire ceci:

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

Vous devez savoir quelle classe concrète construire et dans votre exemple, la seule option possible est myObject. 

Vous pouvez également rechercher un élément appelé «Injection de dépendance», qui vous permet de spécifier le type de classe concrète à «injecter» dans des paramètres qui appellent des interfaces dans des constructeurs ou des champs. Je ne suis pas sûr que votre conception totale, donc cela pourrait être applicable. Dans Dependancy Injection, vous pouvez indiquer dans votre code que IAuditables doit être créé à l'aide de UserAudit, bien qu'il y ait un peu plus de câblage que de simplement appeler "nouveau IAuditable".

4
deepee1

Si vous devez créer une instance pour une interface, vous pouvez créer une classe publique nommée FactoryClass () contenant la méthode Interfaces. vous pouvez utiliser le code suivant:

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
   }
}

Dans la classe Main (), ajoutez le code suivant:

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

Dans le constructeur, ajoutez ce qui suit:

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

vous pouvez appeler la fonction en utilisant le code suivant:

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

Nous ne pouvons pas créer d'instance d'aucune interface .Interface peut contenir une adresse mémoire qui hérite ou implémente cette interface E.g

interface IInterface
{
    void GetData();
}
public class SomeClass : IInterface
{
    public void GetData()
    {
        //do something
    }
}
class Program
    {
        static void Main(string[] args)
        {
        IInterface Iface = new SomeClass();
        Iface.GetData();
         ReadLine();
        }
    }
0
Sunil Dhappadhule