Car*_*ten 8 c# oop generics design-patterns
在C#中,是否可以编写如下内容:
public class MyClass<T> : T
where T : class, new()
{
}
Run Code Online (Sandbox Code Playgroud)
我知道上面的实现没有编译,但我实际上试图实现的是将某种通用包装器实现为未知类型,这样客户端就可以调用包装器,就像调用参数提供的类型一样T而不是用类似的东西来调用它wrapper.Instance.SomeMember().
提前致谢!
这是不可能的。
在我看来,我不认为应该使用继承来实现包装器。
例如,假设我们有一个Engine类,您需要实现一个FerrariEngine. 你有一Car堂课。
你是说Car应该继承FerrariEngine。对我来说看起来很糟糕!
归根结底,您希望使用继承来执行依赖注入之类的操作,但同样,这不是正确的路径。
我的建议是不要试图让你的生活更轻松:根据理性点决定架构。
OP 在一些评论中说:
我想让这个类来管理类型 T 的对象的实例,这样客户端就不需要关心什么时候需要创建实例了。
你不需要做奇怪的事情来得到你想要的:
public interface IEngine
{
void Start();
}
public sealed class FerrariEngine : IEngine
{
public FerrariEngine()
{
Start();
}
public void Start()
{
}
}
public abstract class Car<TEngine> where TEngine: IEngine, new()
{
public Car()
{
_engine = new Lazy<TEngine>(() => new TEngine());
}
private readonly Lazy<TEngine> _engine;
public TEngine Engine
{
get { return _engine.Value; }
}
}
public class FerrariCar : Car<FerrariEngine>
{
}
Run Code Online (Sandbox Code Playgroud)
最后,如果我们创建一个实例FerrariCar:
Car<FerrariEngine> myFerrari = new FerrariCar();
Run Code Online (Sandbox Code Playgroud)
引擎将被实例化并启动,无需开发人员干预!
检查Lazy<T>基本的通用约束如何完成工作;)
总之:
Lazy<T>只有当某些人访问该Engine属性时,才会实例化使用引擎。FerrariEngine实现了一个调用Start()自身的无参数构造函数,它将启动引擎。我相信这个示例向您展示了如何获得您正在寻找的内容并“按原样”使用 C#!