在C#中静态派生类型?

时间:2012-01-02 10:15:33

标签: c# generics typedef traits

我正在寻找C#typedef的C#替代品或特定情况下的traits类。我知道没有直接的等价物,但也许有一些替代解决方案可以解决这个问题吗?

这是我正在尝试做的事情。我正在编写一个框架,其中有三种相关类型。视图,后备存储和工厂。所有三个接口都将有多个实现。视图和工厂之间存在1-1关系,视图和存储之间存在1-N关系。一个具体的impl。该框架看起来像这样:

Storage : IStorage<int> ...

View : IView<Storage> ... // And IView<T> : IViewNonGeneric further up..

Factory : IFactory<Storage> {
  // This needs to take a concrete storage type as arg
  IViewNonGeneric CreateView(Storage s) ... 

  Storage CreateStorage() ...  
}

View类是框架用户最重要的类;其他的都是实施细节。因此,根据View类(而不是存储方面)定义Factory似乎更自然。在C ++中,这将是直截了当的,只需在视图中添加一个typedef并在工厂中使用它,如下所示:

class IView<typename T> { typedef T TStorage; ...

class IFactory<typename T> { 
  IViewNonGeneric CreateView(typename T::TStorage s) ... 

在C#中,我们显然没有typedef或traits类。有没有其他方法可以达到预期的效果?也就是说,可以使用View作为Factory的通用参数,并从View中导出具体的Source类型吗?

2 个答案:

答案 0 :(得分:3)

C#中的泛型绝不像C ++中的模板那么强大。但是,C#确实具有C ++所没有的强大功能:反射。

在视图类上定义一个返回具体类型的存储类的方法(静态或实例)应该非常容易。然后,您可以使用Type.GetConstructor动态查找存储类的构造函数,并使用ConstructorInfo.Invoke方法调用它。

此外,您还可以探索使用可以分配给视图类的自定义属性。这样的事情怎么样:

[StorageType( typeof( MyStorage1 ) ]
class MyView1 { ... }

然后在typeof(MyView1)上使用反射来查看它是否具有与之关联的StorageTypeAttribute。

答案 1 :(得分:0)

我认为你想要的是:

public interface IStorage<T>
{
}

public class IntStorage : IStorage<int>
{
}

public interface IFactory<S, T> where S : IStorage<T>
{
    IView<S, T> CreateView(S storage);
}

public interface IViewNonGeneric
{
}
public interface IView<S, T> : IViewNonGeneric where S : IStorage<T>
{
}

public class IntView : IView<IntStorage, int>
{
}

public class IntFactory : IFactory<IntStorage, int>
{
    public IntView CreateView(IntStorage storage)
    {
        // create the view
    }
    // private interface implementation
    IView<IntStorage, int> IFactory<IntStorage, int>.CreateView(IntStorage storage)
    {
        return CreateView(storage);
    }
}

...