это базовый тип
[DataContract]
public abstract class InputModelBase<T>where T : InputModelParametersBase
{
[DataMember]
public string Token { get; set; }
[DataMember]
public bool Trace { get; set; }
[DataMember(Name = "parameters")]
public T Parameters { get; set; }
}
public class InputModelParametersBase: IInputModelParameters
{
public string staticToken { get; set; }
public bool trace { get; set; }
}
public interface IInputModelParameters
{
public string staticToken { get; set; }
public bool trace { get; set; }
}
эти производные типы:
public class SearchInput: InputModelBase<SearchParameters>
{
}
public class SearchParameters: InputModelParametersBase
{
[DataMember]
public string Query { get; set; }
}
мне нужно создать функцию, которая принимает все производные типы из InputModelBase. я попробовал это, но это не работает
public void someFunction(InputModelBase<InputModelParametersBase> oInputParams)
{
}
вызов исключения someFunction
var oSearchInput = new SearchInput();
someFunction(oSearchInput);
Код серьезности Описание Состояние подавления строки файла проекта Ошибка CS1503 Аргумент 1: невозможно преобразовать из «SearchInput» в «InputModelBase».
как объявить someFunction, чтобы она принимала все производные типы InputModelBase?
@FDB, пожалуйста, также примите во внимание мой ответ, он может принести вам пользу, хотя и добавляет немного накладных расходов.
Сделайте свой метод универсальным методом, как показано ниже.
public void someFunction<T>(InputModelBase<T> oInputParams) where T : InputModelParametersBase
{
}
Я не знаю, почему я получаю негативную реакцию! Подумайте о том, чтобы оставить комментарий, когда вы добавите отрицательный голос за любой ответ, это будет заметно.
Я проголосовал за вас, но в ваших ответах не хватает объяснения, почему это вообще невозможно.
Существует небольшая путаница, если предположить, что InputModelBase<SearchParameters>
наследуется от InputModelBase<InputModelParametersBase>
, поэтому мы можем передать SearchInput
(который наследуется от InputModelBase<SearchParameters>
) как параметр типа InputModelBase<InputModelParametersBase>
.
Но это не так.
InputModelBase<SearchParameters>
и InputModelBase<InputModelParametersBase>
— это разные закрытые универсальные типы, которые передали свои разные универсальные параметры открытому универсальному типу InputModelBase<T>
. Они не оба наследуют его, но если бы они это сделали, они были бы братьями и сестрами, а не родителем и ребенком.
Если мы не хотим использовать универсальные методы, такие как Ибрагим, предложенные в его ответе, мы можем ввести ковариантный интерфейс для нашего общего открытого абстрактного базового класса:
public interface IInputModelBase<out T> where T : InputModelParametersBase {
string Token { get; set; }
bool Trace { get; set; }
InputModelParametersBase Parameters { get; set; }
}
который мы уже реализуем в абстрактном классе
public abstract class InputModelBase<T> : IInputModelBase<T>
where T : InputModelParametersBase {
Это позволит использовать оригинальный способ написания функции OP с той лишь разницей, что мы передаем ссылку на тип интерфейса, а не на абстрактный базовый класс.
public void someFunction(IInputModelBase<InputModelParametersBase> oInputParams) {
}
Возможным недостатком является то, что нам приходится синхронизировать интерфейс и абстрактный базовый класс.
Тоже очень хорошее решение
Вам нужны два общих параметра
Function<M,P>(..) where P : InputModelParametersBase where M : InputModelBase<P>