C# 包含受约束泛型类实例的类型变量

C# 包含受约束泛型类实例的类型变量,c#,generics,inheritance,syntax,C#,Generics,Inheritance,Syntax,我刚刚开始掌握泛型,并且正在(ab)使用它们重构代码中相当复杂的部分(我只使用c#一段时间,但在其他语言中有相当丰富的经验) 我有一个继承结构,其中我的类扩展了一个基类。在基类中,我实现了大部分功能。但我希望能够将这些儿童类与其兄弟姐妹的实例相关联 以下是一些相关代码的简化: class ParentClass<T> where T : ParentClass<T>, new() { public static T Create() {

我刚刚开始掌握泛型,并且正在(ab)使用它们重构代码中相当复杂的部分(我只使用c#一段时间,但在其他语言中有相当丰富的经验)

我有一个继承结构,其中我的类扩展了一个基类。在基类中,我实现了大部分功能。但我希望能够将这些儿童类与其兄弟姐妹的实例相关联

以下是一些相关代码的简化:

class ParentClass<T>
    where T : ParentClass<T>, new()
{

    public static T Create()
    {
        return new T();
    }

    private object joinedItem;

    public void Join<TJoinee>(TJoinee item)
        where TJoinee : ParentClass<TJoinee>, new()
    {
        joinedItem = item;
    }

}

class ChildOne : ParentClass<ChildOne>
{
}

class ChildTwo : ParentClass<ChildTwo>
{
}

问题是,当我真的想将它键入为
ParentClass
时,我需要将
joinedItem
键入为object。是否可以为
joinedItem
指定更具体的类型?或者我只是严重滥用了语言,应该采取完全不同的方法吗?

你能从
父类
中提取一个不依赖于
T
的接口吗?这样就可以在接口中键入
joinedItem

这似乎是您所能做的最远的事情(将
ParentClass
实例连接到
ParentClass
实例)


如果
ParentClass
接口中没有不依赖于
T
的内容,如果不知道
T

的话,就很难找到比object更有用的接口。这里的核心问题是,不可能用任意类型参数来表达变量必须是
XYZ
类型的概念

您可以在参数中表示,然后只需要添加约束(就像您所做的那样),但不能将约束添加到变量中(至少,在不将变量类型添加到类型参数列表中的情况下是如此,这在语法上可能很难看)

因此,如果您需要为任何类型表达
XYZ
的概念,那么您需要将该概念显式表示为一个类型(比如
IXYZ
),并确保所有
XYZ:IXYZ
实际上都继承自该类型。通常,最灵活的方法是通过接口,但是抽象基类也可以


不幸的是,类型类通常不是泛型的一部分;-)

嗯-我可能可以走接口路线。。。我会浏览一下实际的代码,看看是否有任何地方会掉下来……但即使界面中没有独立于T的东西,您所说的仍然是一个好主意,只是为了清楚代码的意图和可读性。即使它只是一个标记接口,编译器仍然会验证您没有进行不可能的强制转换(即,您可以将
对象
向下转换为
字符串
,但不能将
IJoinable
向下转换为
字符串
-
字符串
未实现
IJoinable
),谢谢您的回答。当你说“不将变量类型添加到类型参数列表中”时,你是说在类级别添加类型参数吗?在你的例子中,是的,你需要在类级别添加类型参数,因为你想专门化类的变量--但我不建议这样做,这可能会降低代码的可维护性。然而,我所说的只是您使用的构造,其中Join方法有一个受约束的泛型类型参数TJoinee。在任何情况下-当有疑问时,使用接口来指定所需的行为;这可能会更简单、更灵活(因为一个类可以实现很多接口)。我走了接口路线,一切似乎都很好!
var a = ChildOne.Create();
a.Join(new ChildTwo());