简体   繁体   English

将 Generic 的实例作为参数发送

[英]Send Instance of Generic as a parameter

I have an abstract Group class and an abstract Member class.我有一个抽象的Group类和一个抽象的Member类。 Group class has a field (property) of Member class called member , and Member has a field of Group class called group . Group 类有一个名为member的 Member 类的字段(属性),而 Member 有一个名为group的 Group 类的字段。

They both must be inherited that way, so we have DerGroup and DerMember and DerGroup has the member field of DerMember and DerMember has the group field of Group class.他们都必须继承这种方式,所以我们必须DerGroupDerMember和DerGroup具有DerMember成员字段和DerMember具有集团级的字段。

I am trying to use Generics for that.我正在尝试使用泛型。

abstract class Member
{
    public Group<Member> group;
    public void Init(Group<Member> grp)
    {
        group = grp;
    }
}

abstract class Group<T> where T : Member
{
    public T member;
    public void InitMember()
    {
        // Here I have an Error: Can't convert Group<T> to Group<Member>
        member.Init(this);
    }
}

How do I send this Group instance to its Member instance if Group is Generic?如果 Group 是 Generic,如何将此Group 实例发送到它的 Member 实例? I am using Generics to be able to inherit Group and Member classes and save their relations.我正在使用泛型来继承 Group 和 Member 类并保存它们的关系。 Like that:像那样:

class Student : Member {}
class ClassRoom<T> : Group<Member> where T : Student {}

So we can have this: typeof(ClassRoom.member) = Student , and not Member所以我们可以有这个: typeof(ClassRoom.member) = Student ,而不是Member

Give me any help of how to properly declare Member.Init() function or get this done.给我任何有关如何正确声明Member.Init()函数或完成此操作的帮助。

I am afraid you may have gone down the GRHOM - Generic Rabbit Hole of Madness.恐怕你已经去了 GRHOM - 疯狂的通用兔子洞。 If you look around you'll see my claw marks.如果你环顾四周,你会看到我的爪痕。

The relationship between these classes is very difficult to follow because it indicates that a group can only have one member and a member can only belong to one group.这些类之间的关系很难理解,因为它表明一个组只能有一个成员,一个成员只能属于一个组。

What it looks like you're trying to do is circular.看起来你想要做的是循环。 You're trying to ensure that groups only have one sort of member, and members only belong to groups which contain members which are only members of that sort of group... etc.您试图确保组只有一种成员,并且成员仅属于包含仅属于该组成员的成员的组......等等。

The question is, why do you need to constrain this both ways?问题是,为什么需要双向限制? Given this:鉴于这种:

class Group<T> : Group where T : Member

You've already ensured that a Group can only contain Member or a subclass of Member - whatever T is when you define your concrete class.你已经确保了Group只能包含Member或子类Member -无论T是,当你定义你的具体类。

Why, then, does a Member need to also specify that it can only belong to groups which can only have it as a member?那么,为什么一个Member还需要指定它只能属于只能将其作为成员的组? That constraint has already been accomplished.该约束已经完成。

Assuming that groups must contain references to members and members to groups, you could do this:假设组必须包含对成员的引用和对组的成员的引用,您可以这样做:

abstract class Member
{
    private List<Group> Groups { get; } = new List<Group>();

    internal void AddGroup(Group group)
    {
        Groups.Add(group);
    }
}

abstract class Group
{
    protected List<Member> Members { get; } = new List<Member>();
}

abstract class Group<TMember> :Group  where TMember : Member
{
    void AddMember(TMember member)
    {
        Members.Add(member);
        member.AddGroup(this);
    }
}

Now groups can be constrained by the type of members, but members has a reference to a non-constrained set of groups.现在,组可以受成员类型的约束,但成员可以引用一组不受约束的组。

It might be simpler just to avoid having members reference groups.避免让成员参考组可能更简单。 If you want to know which groups a member is in, query the groups to see which ones contain a given member.如果您想知道成员在哪些组中,请查询组以查看哪些组包含给定成员。

I don't really understand what you're trying to build with these classes (I mean, your core business), but you could introduce an interface:我真的不明白你想用这些类构建什么(我的意思是你的核心业务),但你可以引入一个接口:

abstract class Member
{
    public IGroup<Member> group;
    public void Init(IGroup<Member> grp)
    {
        group = grp;
    }
}

interface IGroup<T> where T : Member
{
    T member { get; set; }
}

abstract class Group<T> : IGroup<Member>
{
    public Member member { get; set; }

    public void InitMember()
    {
        member.Init(this);
    }
}

class Student : Member { }

class ClassRoom<T> : Group<Student> where T : Student { }

Working fiddle here .在这里工作小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM