Reputation: 185
Suppose I have a list of many (say, 10) classes A1,..., A10 which all inherits from a base class A
and I have a one-to-one mapping from them to 10 other classes B1,...,B10. I also have a generic class MyClass<T>
And I wish to have a function Func(A a)
which creates a MyClass<B1>
instance if the input is an instance of A1
, creates a MyClass<B2>
instance if the input is an instance of A2
, etc. I can do it using a switch statement but it gets messy if the number of classes grows. What is a good way of doing this?
Here is an concrete example: say the A classes are Cat
and Dog
, and the B classes are Foo
and Bar
, and I have another Generator class to generate these instances.
public class Generator{
public Foo Generate(Cat c){
// some code
}
public Bar Generate(Dog d){
// some code
}
}
and I have a generic class below
public class MyClass<T>{
private T _t;
public MyClass(T t){
this._t = t;
}
}
Now in the code I want to do something like this
Generator gen = new Generator();
dynamic animal = new Dog();
var result = gen.Generate(animal); // can be of type Foo or Bar
var cl = new MyClass(result); // does not compile!
The last line does not compile because it is missing a generic type argument.
Please let me know if there's more details needed!
Upvotes: 0
Views: 100
Reputation: 1555
Do note that when working with dynamics like this, it can be hard to break away from using dynamics upstream. To specify the generic argument, one approach would be to create a factory method where the type can be inferred:
namespace ConsoleApp13
{
public class Program
{
public static void Main() {
Generator gen = new Generator();
dynamic animal = new Dog();
var result = gen.Generate(animal); // can be of type Foo or Bar
var myClass = MyClass.Create(result);
}
}
public static class MyClass
{
public static MyClass<T> Create<T>(T value) => new MyClass<T>(value);
}
public class Generator{
public Foo Generate(Cat c){
// some code
return new Foo();
}
public Bar Generate(Dog d){
// some code
return new Bar();
}
}
public class MyClass<T>{
private T _t;
public MyClass(T t){
this._t = t;
}
}
public class Dog
{
}
public class Bar
{
}
public class Cat
{
}
public class Foo
{
}
}
But as other have said, in this case this is not necessary if you have class A
creating B
as dynamics and the Generator
class will no longer needed:
namespace ConsoleApp13
{
public class Program
{
public static void Main() {
var animal = new Dog();
var myClassWithoutNewMethod = new MyClass<Bar>(animal.GetBar());
var myClass = MyClass.Create(animal);
}
}
public static class MyClass
{
public static MyClass<T> Create<T>(T value) => new MyClass<T>(value);
}
public class MyClass<T>{
private T _t;
public MyClass(T t){
this._t = t;
}
}
public class Dog
{
public Bar GetBar()
{
return new Bar();
}
}
public class Bar
{
}
public class Cat
{
}
public class Foo
{
}
}
Upvotes: 1
Reputation: 808
Can each type of A know how to produce it's corresponding B? Then you don't have to have a big decision tree testing the type of A in some separate code that then creates Bs...that code simply calls a.GetB().
Upvotes: 2