How do create groups of related types for use in c# generics

本文关键字:use for in generics types related do create groups of How | 更新日期: 2023-09-27 18:24:10

作为一个来自C++背景的人,我遇到了以下情况:

既然c#不支持typedefs,那么如何以编程方式关联类型呢。也就是说,在C++中,当与模板一起使用时,我可以将相关类型存储为typedef以供检索。由于缺少typedef,在c#中不能以同样的方式完成同样的事情。

例如,在C++中,我会:

template< typename T >
class Thing : public ThingBase<T>
{
   public:
       bool isRelated( T::Parent & otherThing )
       {
           T::Auxillary aux( "Yes" );            
           return aux.isValid( otherThing ) && data.isParent( otherThing );
       }
   private:
       T data;
};

这将适用于以下任何一种:

class SomeClass
{
    public:
        typedef SomeClassParent Parent; 
        typedef FooAuxillary    Auxillary;
        bool isParent( Parent & parentObject );
};
class OtherClass
{
    public:
        typedef OtherClassParent Parent; 
        typedef BarAuxillary     Auxillary;
        bool isParent( Parent & parentObject );
};

虽然可以通过公共接口接口对参数类型调用T::isParent,但如果没有typedefs,为Thing::isRelated构建签名似乎是不可能的。

那么,在C#中,我该如何获得T的相关接口类型(在C++示例中是T::interface)?

How do create groups of related types for use in c# generics

您需要使用Generic约束(在这种情况下很可能)作为SLaks的第二个泛型参数,如图所示。

interface IRelated<TRelated>
{
    bool isParent(TRelated parentObject);
}
class SomeClassParent {}
class SomeClass : IRelated<SomeClassParent>
{
    bool isParent(SomeClassParent parentObject)
    {
        // your logic here
        return true;
    }
}
class Thing<T, TParent> : ThingBase<T> where T : IRelated<TParent> {}

使用:

var obj = new Thing<SomeClass, SomeClassParent>();

这是另一个选择。这需要一些运行时类型检查(并允许使用任何类型的对象调用isParent),但它清理了语法。

interface IRelated
{
    bool isParent<T>(T parentObject);
}
class SomeClassParent {}
class SomeClass : IRelated
{
    bool isParent<T>(T parentObject)
    {
        if (parentObject is SomeClassParent)
        {
            // your logic here
            return true;
        }
    }
}
class Thing<T> : ThingBase<T> where T : IRelated {}

使用:

var obj = new Thing<SomeClass>();

使用一个通用接口来关联类型:

interface IRelatedTo<TRelated> 
class Thing<T, TRelated> where T : IRelatedTo<TRelated>