[英]Create different generic objects based on argument type in C#
假設我有一個包含許多(比如 10 個)類 A1,..., A10 的列表,它們都繼承自基類A
並且我有從它們到其他 10 個類 B1,...的一對一映射, B10. 我還有一個通用類MyClass<T>
並且我希望有一個函數Func(A a)
如果輸入是A1
的實例,它會創建一個MyClass<B1>
實例,如果輸入是,則創建一個MyClass<B2>
實例A2
一個實例等。我可以使用 switch 語句來完成,但如果類的數量增加,它會變得混亂。 這樣做的好方法是什么?
這是一個具體的例子:假設 A 類是Cat
和Dog
,B 類是Foo
和Bar
,我有另一個 Generator 類來生成這些實例。
public class Generator{
public Foo Generate(Cat c){
// some code
}
public Bar Generate(Dog d){
// some code
}
}
我在下面有一個通用類
public class MyClass<T>{
private T _t;
public MyClass(T t){
this._t = t;
}
}
現在在代碼中我想做這樣的事情
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!
最后一行無法編譯,因為它缺少泛型類型參數。
如果需要更多詳細信息,請告訴我!
每種類型的A都知道如何生產它對應的B嗎? 然后你不必有一個大的決策樹在一些單獨的代碼中測試 A 的類型,然后創建 Bs ......該代碼只需調用 a.GetB()。
請注意,在使用這樣的動態時,很難擺脫在上游使用動態。 要指定泛型參數,一種方法是創建一個可以推斷類型的工廠方法:
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
{
}
}
但正如其他人所說,在這種情況下,如果您讓A
類創建B
作為動態並且不再需要Generator
類,則不需要:
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
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.