是否可以使对象公开类型参数的接口?

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().

提前致谢!

Mat*_*zer 5

这是不可能的。

在我看来,我不认为应该使用继承来实现包装器。

例如,假设我们有一个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#!