#c# #.net
#c# #.net
Вопрос:
Допустим, я наследую от IMyManager setModel. Если бы я это реализовал, я бы обычно написал:
using lib.model;
namespace MyComponents
{
public class MyManager:IMyManager
{
public void SetModel(ILibModel model)
{
}
}
}
Это нормально для компилятора.
Теперь предположим, что вместо ILibModel я передаю конкретный класс MyModel, который реализует ILibModel.
Почему компилятор не принимает это, тогда как MyModel имеет тип ILibModel :
namespace MyComponents
{
public class MyManager:IMyManager
{
public void SetModel(MyModel model) {
}
}
}
Ответ №1:
Предполагая, что это MyModel
реализует ILibModel
причину, по которой это не работает, заключается в том, что, хотя все MyModel
типы являются ILibModel
типами, обратное не выполняется. Это означает, что не все ILibModel
типы являются MyModel
типами.
В интерфейсе явно указано, что он ДОЛЖЕН принимать ILibModel
типы. Итак, реализация, которая принимает just MyModel
, не соответствует вашему контракту на интерфейс из-за того факта, что тип, скажем, MyOtherModel
который также реализует ILibModel
, является допустимым типом, который должен передаваться на основе контракта вашего интерфейса.
Единственным способом обойти это было бы потенциально использовать обобщения в интерфейсе. Примером является:
public interface IMyManager<TModel>
where T : ILibModel
{
void SetModel(TModel model);
}
public class MyManager : IMyManager<MyModel>
{
void SetModel(MyModel model)
{
}
}
Однако в такой системе вы можете столкнуться с проблемами, связанными с совместными и противоположными различиями.
Комментарии:
1. обратное не выполняется, но я не в обратном случае. Проблема скорее в том, что этот глупый интерфейс просто автоматически не выполняет приведение, тогда как должен.
2. Спасибо за дженерики, посмотрим, подойдет ли это.
Ответ №2:
Потому что вы предоставляете перегрузку для функции setModel. Что касается компилятора, возможно, вы хотите разрешить программисту делать что-то более конкретное с конкретным типом, одновременно выполняя что-то еще с версией интерфейса.
Ответ №3:
потому что кто-то мог позже написать:
((IMyManager)myManager).SetModel(new OtherClassThatImplementsILibModel());
Ответ №4:
Потому что так IMyManager
определяется SetModel
.