c # пропустить параметры вложенного типа - PullRequest
0 голосов
/ 30 августа 2018

Я хочу создать класс Operation с функцией, которая принимает Данные в качестве входных данных и предоставляет Данные в качестве выходных данных:

public abstract class Data { }

public abstract class Operation {
    public abstract Data Run (Data input);
}

Мне нужна гибкость различных данных выходных данных, чем данных входных данных:

public abstract class Data { }

public abstract class Operation<T1, T2>
  where T1: Data
  where T2: Data
{
  public abstract T2 Run (T1 input);
}

Наконец, я хочу заставить все Данные реализовать Список некоторого типа:

public abstract class Data<T> : List<T> { }

public abstract class Operation<T1, T2>
  where T1: Data // Error
  where T2: Data // Error
{

  public abstract T2 Run (T1 input);
}

Затем я получаю сообщение об ошибке: «Использование универсального типа« Данные »требует аргументов 1 типа» .

Как мне разрешить эту ошибку, не задавая явно тип данных в предложении where?

В идеале нужно, чтобы работал следующий код:

public class Operation <????> { ???? }

public class Data<T> : List<T> {}
public class Foo {}
public class FooData : Data<Foo> {}
public class Bar {}
public class BarData : Data<Bar> {}

public class FBOperation : Operation<FooData, BarData> {
  public override BarData Run (FooData input) {
    return ...; 
  }
}

Как мне реализовать класс Operation?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Проблема в том, что у вас больше нет типа Data, вы добавили к нему универсальный параметр T и получили совершенно другой тип Data<T>, поэтому ограничение where T1: Data не является правильный.

Наиболее простым решением является распространение этого дополнительного параметра на тип Operation.

public abstract class Operation<T1, T2, TItem>
  where T1: Data<TItem> 
  where T2: Data<TItem> 
{

  public abstract T2 Run (T1 input);
}

Но все немного сложнее, чем для меня. Имеет смысл подумать о том, каковы преимущества добавления этих довольно жестких ограничений в ваш класс Operation<,>. Этой базовой версии может быть достаточно для описания семейства типов операций.

public abstract class Operation<T1, T2>
{
    public abstract T2 Run (T1 input);
}
0 голосов
/ 30 августа 2018

Вы можете сделать что-то вроде этого:

public class Foo { }


public class Bar { }


public interface IData { }


public interface IData<T> : IData
{
    List<T> List{ get; set; }
}


public class Foos : IData<Foo>
{
    public List<Foo> List{ get; set; }
}


public class Bars : IData<Bar>
{
    public List<Bar> List{ get; set; }
}


public abstract class Operation<TD1, TD2>
    where TD1 : IData
    where TD2 : IData
{
    public abstract TD2 Run(TD1 input);
}


public class FbOperation : Operation<Foos, Bars>
{
    public override Bars Run(Foos input)
    {
        // TODO
        return new Bars();
    }
}
...