实例化 class 的通用字段
Instantiating a generic field of a class
有没有办法让 class 中的泛型字段专用于构造函数中的特定类型?
例如:
class concreteClass1
{
private int a;
public concreteClass1( int a)
{
this.a = a;
}
}
class concreteClass2
{
string b;
public concreteClass2(string b)
{
this.b = b;
}
}
class A<T>
{
private T field;
public A(int x)
{
field = new concreteClass1(x); //error here CS0029
}
public A(string y)
{
field = new concreteClass2(y); //error here CS0029
}
}
因此 T
可以是 concreteClass1
或 concreteClass1
并且它们各自的 ctors 将具有不同的签名。
好吧,由于必须转换类型,这有点棘手。也许这对你有用?
class Program
{
static void Main(string[] args)
{
var myImplementation = new Implementation<int>(4);
var myImplementation2 = new Implementation<string>("Hello World");
Console.WriteLine(myImplementation.myConcreteField); // outputs 4!
Console.WriteLine(myImplementation2.myConcreteField); // outputs Hello World
}
}
abstract class MyAbstract<T>
{
public T MySomething;
public MyAbstract(T something)
{
MySomething = something;
}
}
class ConcreteA<T> : MyAbstract<T>
{
public ConcreteA(int something) : base((T)Convert.ChangeType(something, typeof(T)))
{
}
}
class ConcreteB<T> : MyAbstract<T>
{
public ConcreteB(string something) : base((T)Convert.ChangeType(something, typeof(T)))
{
}
}
class Implementation<T>
{
public MyAbstract<T> myConcreteField;
public Implementation(T a)
{
myConcreteField = new ConcreteA<T>(4);
}
void DoSomething()
{
Console.Write(myConcreteField.MySomething.ToString());
}
}
我会重构它以使用依赖注入。这样 class 就不会包含创建它所依赖的其他 class 的代码,例如 myConcreteField = new ConcreteA<T>(4);
。依赖注入用于防止代码陷入这样的难题。
(你的例子非常非常抽象,这让它有点困难。如果你使用 class 名称,如 "Concrete" 和 "Implementation" 那么它会使答案更难阅读因为我们使用相同的词来描述概念。)
相反,无论 Concrete
是什么,声明一个接口,例如
public interface ISomethingThatTheOtherClassNeeds<T>
{
public int MySomething {get;set;}
}
public class SomethingThatTheOtherClassNeeds : ISomethingThatTheOtherClassNeeds<string>
{
public int MySomething {get;set;}
}
然后在你的 Implementation
class:
class Implementation<T>
{
private readonly ISomethingThatTheOtherClassNeeds<T> _something;
public Implementation(ISomethingThatTheOtherClassNeeds<T> something)
{
_something = something;
}
void DoSomething()
{
Console.Write(_something.MySomething.ToString());
}
}
不同之处在于,它不是负责创建 class 的任何内容,而是在构造函数中传递给 Implementation
。 Implementation
甚至不知道 class 是什么 - 它只知道它与界面匹配。
如果其他 classes 又依赖于更多 classes,这将特别有用。如果您通过在 class 中调用 new
创建它们,那么 class 必须知道如何创建那些 classes。
然后要连接它,您将使用依赖注入容器,如 Windsor、Unity、Autofac 等。这在控制台应用程序中并不常见,但我猜这是实验性的,而不是真实的。
有没有办法让 class 中的泛型字段专用于构造函数中的特定类型?
例如:
class concreteClass1
{
private int a;
public concreteClass1( int a)
{
this.a = a;
}
}
class concreteClass2
{
string b;
public concreteClass2(string b)
{
this.b = b;
}
}
class A<T>
{
private T field;
public A(int x)
{
field = new concreteClass1(x); //error here CS0029
}
public A(string y)
{
field = new concreteClass2(y); //error here CS0029
}
}
因此 T
可以是 concreteClass1
或 concreteClass1
并且它们各自的 ctors 将具有不同的签名。
好吧,由于必须转换类型,这有点棘手。也许这对你有用?
class Program
{
static void Main(string[] args)
{
var myImplementation = new Implementation<int>(4);
var myImplementation2 = new Implementation<string>("Hello World");
Console.WriteLine(myImplementation.myConcreteField); // outputs 4!
Console.WriteLine(myImplementation2.myConcreteField); // outputs Hello World
}
}
abstract class MyAbstract<T>
{
public T MySomething;
public MyAbstract(T something)
{
MySomething = something;
}
}
class ConcreteA<T> : MyAbstract<T>
{
public ConcreteA(int something) : base((T)Convert.ChangeType(something, typeof(T)))
{
}
}
class ConcreteB<T> : MyAbstract<T>
{
public ConcreteB(string something) : base((T)Convert.ChangeType(something, typeof(T)))
{
}
}
class Implementation<T>
{
public MyAbstract<T> myConcreteField;
public Implementation(T a)
{
myConcreteField = new ConcreteA<T>(4);
}
void DoSomething()
{
Console.Write(myConcreteField.MySomething.ToString());
}
}
我会重构它以使用依赖注入。这样 class 就不会包含创建它所依赖的其他 class 的代码,例如 myConcreteField = new ConcreteA<T>(4);
。依赖注入用于防止代码陷入这样的难题。
(你的例子非常非常抽象,这让它有点困难。如果你使用 class 名称,如 "Concrete" 和 "Implementation" 那么它会使答案更难阅读因为我们使用相同的词来描述概念。)
相反,无论 Concrete
是什么,声明一个接口,例如
public interface ISomethingThatTheOtherClassNeeds<T>
{
public int MySomething {get;set;}
}
public class SomethingThatTheOtherClassNeeds : ISomethingThatTheOtherClassNeeds<string>
{
public int MySomething {get;set;}
}
然后在你的 Implementation
class:
class Implementation<T>
{
private readonly ISomethingThatTheOtherClassNeeds<T> _something;
public Implementation(ISomethingThatTheOtherClassNeeds<T> something)
{
_something = something;
}
void DoSomething()
{
Console.Write(_something.MySomething.ToString());
}
}
不同之处在于,它不是负责创建 class 的任何内容,而是在构造函数中传递给 Implementation
。 Implementation
甚至不知道 class 是什么 - 它只知道它与界面匹配。
如果其他 classes 又依赖于更多 classes,这将特别有用。如果您通过在 class 中调用 new
创建它们,那么 class 必须知道如何创建那些 classes。
然后要连接它,您将使用依赖注入容器,如 Windsor、Unity、Autofac 等。这在控制台应用程序中并不常见,但我猜这是实验性的,而不是真实的。