Search code examples
c#listconstructortype-parameter

c# omit nested type parameters


I want to create an Operation class with a function that takes Data as input and provides Data as output:

public abstract class Data { }

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

I want the flexibility of different Data output than Data input:

public abstract class Data { }

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

Lastly, I want to force all Data to implement a List of some type:

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);
}

Then I get the error: "Using the generic type 'Data' requires 1 type arguments".

How am I supposed to resolve this Error without explicitly setting a type of Data in the where clause?

Ideally want to have the following code work:

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 ...; 
  }
}

How am I supposed to implement the Operation class?


Solution

  • You could do something like this:

    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();
        }
    }