Divymital Ответов: 1

Поведение интерфейса и класса В C# с отражением


Привет,

Во время разработки моего проекта я наблюдал странное поведение (в соответствии с моим пониманием концепций ООП) интерфейса и класса. Ниже приведены подробности:

У меня есть класс DBOperations, который включает в себя 2 интерфейса IReadOnly и IDML.

class DBOperations : IDML,IReadOnly
    {
        public string UpdateDB()
        {
            return "Update Data";
        }

        public string SelectData()
        {
            return "Select Data";
        }
    }


public interface IDML
    {
        string UpdateDB();
    }


public interface IReadOnly
   {
       string SelectData();
   }


Идея заключается в том, что для некоторых операций я хотел бы использовать интерфейс IReadOnly и для операций CRUD, я хотел бы использовать интерфейс и idml.

В моем вызывающем классе я могу получить доступ
UpdateDB
метод из интерфейса IDML из ссылки интерфейса IReadOnly !

IReadOnly objIReadOnly = new DBOperations();
            IDML objIDML = new DBOperations();
            
            Console.WriteLine(objIReadOnly.SelectData());
            Console.WriteLine(objIDML.UpdateDB());
            Console.WriteLine(objIReadOnly.GetType().GetMethod("UpdateDB").Invoke(objIReadOnly, null)); // Able to execute UpdateDB method Why ??


Пожалуйста, посоветуйте, как себя вести.

Заранее спасибо !


С уважением,
Дивья

Что я уже пробовал:

Нужна помощь в понимании поведения.

Sinisa Hajnal

Просто от чтения кода (не проверял):
Потому что gettype возвращает тип класса и DBOperations содержит команды updatedb.

Если вы попробуете objIReadOnly.UpdateDB он должен потерпеть неудачу, но, вызывая из экземпляра объекта, вы получаете доступ из класса, а не из интерфейса.

1 Ответов

Рейтинг:
0

OriginalGriff

Поскольку объект objIReadOnly содержит ссылку на объект DBOperations, который реализует оба интерфейса и, следовательно, имеет оба метода.

Когда вы используете отражение, это происходит во время выполнения: объект исследуется, а метод этой сигнатуры находится (если он существует) и выполняется. Поскольку объект, на который ссылается ваша переменная, реализует как интерфейсы IDML, так и ireadonly, он также реализует как UpdateDB, так и SelectData, поэтому отражение может найти оба метода и вызвать их. Во время выполнения тип переменной не имеет значения: используется объект, на который она ссылается. Если запрошенный метод найден, возникает исключение времени выполнения.
Время компиляции отличается: он использует тип переменной, чтобы решить, существует ли объект определенно во всех объектах, на которые можно ссылаться. Если так, то прекрасно. В противном случае генерируется ошибка компилятора, и код не может быть запущен.


Divymital

Спасибо за ответ. Я согласен, но не является ли это недостатком использования интерфейса, поскольку класс, использующий интерфейс IReadOnly, имеет право работать только с методом SelectData, однако если класс может каким-либо образом получить доступ к обновленным данным (здесь отражение), это может быть проблемой безопасности.Не могли бы вы предложить какой-нибудь подход или обходной путь (если таковой имеется), чтобы класс, использующий интерфейс IReadOnly, не мог получить доступ к методу UpdateDb даже с отражением ?