Создание экземпляра интерфейса
У меня определены следующие интерфейсы:
public interface IAudit {
DateTime DateCreated { get; set; }
}
public interface IAuditable {
IAudit Audit { get; set; }
}
Интерфейс 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;
}
}
Теперь, если объект, который является IAuditable
(User
сверху), я хотел бы иметь возможность создавать intance IAudit
(UserAdit сверху) путем подачи объекта IAuditable
в конструктор, В идеале у меня было бы что-то вроде:
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
Я уверен, что это шаблон дизайна, который у многих был раньше, но я не могу опустить его в голову. Я был бы очень признателен, если бы кто-нибудь мог показать мне, как это может быть достигнуто.
Ответы
Ответ 1
Нет, где в коде он определяет, какой IAudit относится к IAuditable Я не могу указать, что интерфейс IAudit должен иметь конструктор, который принимает IAuditable
Вы можете исправить эти два, добавив функцию CreateAudit()
к вашему IAuditable
. Затем вы получите IAudit
, созданный с помощью IAuditable
. В качестве бонуса, если вы хотите сохранить ссылку на IAudit
в IAuditable
(или наоборот), чтобы вы могли связать их друг с другом, довольно легко реализовать класс реализации. Вы также можете добавить GetAuditable()
в IAudit
, чтобы получить IAuditable
, из которого он был создан, например.
Простая реализация будет выглядеть так (в классе, реализующем IAuditable):
public IAudit CreateAudit()
{
UserAudit u = new UserAudit(UserName);
return u;
}
Ответ 2
Вы не можете создать экземпляр интерфейса
Правильно. Вы создаете экземпляр объекта, реализующего интерфейс:
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
Правильно, вы не можете. См. здесь. Вам нужно создать такой конструктор для исполнителей.
Ответ 3
Один из способов - использование дженериков.
Как только у вас есть тип T, который реализует интерфейс я и имеет открытый конструктор без параметров, вы можете создать экземпляр T:
public void Create<T> where T : IAudit, new()
{
T instance = new T();
// TODO: Your logic using such T instance of IAudit implementation
}
Я не знаю вашу архитектуру или цель кода, но вы можете создать метод factory, подобный приведенному выше, для создания экземпляров объектов IAudit.
Ответ 4
Очевидно, вы не можете создать экземпляр интерфейса, но если вы действительно пытались создать экземпляр прошедшего в классе, вы могли бы сделать это:
IAuditable j = ((IAuditable)Activator.CreateInstance(myObject.GetType()));
Вам нужно знать, какой конкретный класс построить, и в вашем примере единственным вариантом является myObject.
В качестве альтернативы вы можете исследовать что-то под названием "Dependancy Injection", которое позволяет вам указать, какой тип конкретного класса "вводить" в параметры, вызывающие интерфейсы в конструкторах или в полях. Я не уверен, что ваш общий дизайн, так что это может быть применимо. В Injection Dependancy вы можете указать в своем коде. IAuditables должен быть создан с использованием UserAudit, хотя есть немного больше подключений, чем просто вызов "new IAuditable"
Ответ 5
Если вам нужно создать экземпляр для интерфейса, вы можете создать открытый класс с именем FactoryClass(), который содержит весь метод Interfaces. вы можете использовать следующий код:
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.
вы можете вызвать функцию, используя следующий код:
newinter.display() //display() is the method in the interface.