我正在寻找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类型吗?
答案 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);
}
}
...