【问题标题】:Make one instance of a class hold a collection of instances of another class in C#在 C# 中,使一个类的一个实例包含另一个类的实例的集合
【发布时间】:2021-12-23 08:56:27
【问题描述】:

C# 和 OOP 编程新手。我了解继承部分等。

我坚持的(对于一个小型学校项目)如下:

  • 我有一个名为 Team 的班级
  • 我有一个名为 TeamMember 的基类
  • 我有 3 个类(更具体的团队角色)继承自 TeamMember
  • 每个团队只能有一定数量的团队成员(即每个团队 10 名团队成员)

团队不继承任何其他类,但(在现实世界中)团队确实有团队成员(否则当然没有团队)。

在 Team 和 TeamMember(或更具体的角色)之间建立连接以使 Team 的 1 个实例有 10 个 TeamMember 的实例“在其中”的正确方法是什么?

这可以通过数组来实现吗?如果是这样,我应该在哪个类中初始化这个数组以及如何用正确的对象填充它?

(如果我的术语没有达到应有的水平,请原谅。我还在那儿学习,如果我可以在某处改进,请纠正我,我会编辑它)

【问题讨论】:

    标签: c# oop instance


    【解决方案1】:

    我对 OOP 不是很陌生,但我不是一个非常聪明的开发人员。 这很有趣,它是关于你如何设计 3 类 TeamMember 的孩子。

    我建议您将每种类型的 TeamMembers 封装在 Team 类中 试着想象在你的团队中你会有很多人,在那之后 它是关于如何设计团队中 ppl 的层次结构。 在我的例子中,我将成员分为 3 个 TeamMember 的孩子列表。每个类都有特殊的属性 prop1,prop2,prop3 (当您考虑 OOP 时,您将不得不考虑要重用什么,为不同类的每个成员提供的不同字段/方法是什么)。

    例如

       //Rextester.Program.Main is the entry point for your code. Don't change it.
    //Microsoft (R) Visual C# Compiler version 2.9.0.63208 (958f2354)
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    namespace Rextester
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                //Your code goes here
                Console.WriteLine("Hello, world!");
                Team t =new Team();
                t.AddTeamMember(  new TeamMembers_Child1(){ name ="n1" ,prop1 ="I'm a staff"   } );
                t.AddTeamMember(  new TeamMembers_Child2(){ name ="n2" ,prop2 ="I'm a manager"   } );
                t.AddTeamMember(  new TeamMembers_Child3(){ name ="n3" ,prop3 ="I'm a janitor"  } ); 
                t.AddTeamMember(  new TeamMembers_Child2(){ name ="n4" ,prop2 ="I'm an imposter "   } );
            }
        }
          
        public class TeamMember{
            public string name {get;set;}   
        }
         public class TeamMembers_Child1 : TeamMember{ 
             public string prop1 {get;set;}
        }
         public class TeamMembers_Child2 : TeamMember{ 
             public string prop2 {get;set;}
        }
         public class TeamMembers_Child3 : TeamMember{ 
             public string prop3 {get;set;}
        }
    
        public class Team{
            private List<TeamMembers_Child1> _member_role1;
            private List<TeamMembers_Child2> _member_role2;
            private List<TeamMembers_Child3> _member_role3;
            public Team(){
                _member_role1 = new  List<TeamMembers_Child1>();
                _member_role2 = new  List<TeamMembers_Child2>();
                _member_role3 = new  List<TeamMembers_Child3>(); 
            }
            /* as Andrei Dragotoniu 's answer the logic of Adding member will be in this function like team only have 2 manager , etc.*/
            public void AddTeamMember(TeamMember newTeamMember)
            {
                if (newTeamMember == null) return;
                else   if (this._member_role1.Count + this._member_role2.Count + this._member_role3.Count  < 10){
                   if( newTeamMember is  TeamMembers_Child1)
                   { 
                    this._member_role1.Add( ( TeamMembers_Child1 )newTeamMember);
                       
                Console.WriteLine("Add role1");
                   }else  if( newTeamMember is  TeamMembers_Child2)
                   { 
                    this._member_role2.Add(( TeamMembers_Child2 )newTeamMember);
                       
                Console.WriteLine("Add role2");
                   } else if( newTeamMember is  TeamMembers_Child3)
                   { 
                    this._member_role3.Add(( TeamMembers_Child3 )newTeamMember);
                       
                Console.WriteLine("Add role3");
                   }
                
                }
        
              
            }
        
        
         
        
        }
    }
    
    
    result  
    > Hello, world! 
    > Add role1 
    > Add role2 
    > Add role3 
    > Add role2
    

    【讨论】:

    • 谢谢!这对我有很大帮助!
    • @Xavvey 不,这只是非常基础的级别,它只是关于投射子父类。和封装就像使用私有/公共。但在现实世界中你将不得不考虑更多,比如如果在团队中你想知道谁是别人的下属关系怎么办?团队成员的班级可能有方法添加下属之类的。
    【解决方案2】:

    一个很好的方法是做这样的事情:

    public class Team
    {
        private List<TeamMember> _teamMembers;
    
        public Team()
        {
            this._teamMembers = new List<TeamMember>();
        }
    
        public void AddTeamMember(TeamMember newTeamMember)
        {
            if (newTeamMember == null) return;
    
            if (this._teamMembers.Count < 10)
                this._teamMembers.Add(newTeamMember);
        }
    }
    

    那么,我们这里有什么?

    我没有使用固定长度的数组然后依赖异常,而是介绍了一种控制团队成员的简单方法。

    该类属性是私有的,因此您不能直接向其添加任何内容。

    相反,我创建了一个公共方法,它公开了一种将成员添加到所述列表的方法,这是我们控制可以添加多少团队成员的地方。

    我喜欢在构造函数中实例化列表属性,因此当您使用该类时,您无需检查该列表是否存在,而是在 Team 实例出现后立即将其初始化为一个空列表创建,然后就少了一件需要担心的事情。

    然后我们可以做出更多的设计决策,也许我们希望该方法返回一个布尔结果,如果添加了某人则返回 true,如果我们没有添加则返回 false,因为我们已经有 10 个。

    现在,您说 TeamMember 是其他类的基类。这意味着您可以将所有这些课程传递给您的团队。

    假设你有这样的东西:

    public class SomeMember : TeamMember
        {
        }
    

    您仍然可以像这样将其添加到您的列表中:

    var team = new Team();
    
    var someMember = new SomeMember();
    
    team.AddTeamMember(someMember);
    

    代码之所以有效,是因为它基于基类,并且是一种常见的做事方式。例如,如果你有一个界面,它也可以工作。

    但是,要记住的一件事是,如果您这样做,那么您将无法访问其他类提供的任何额外东西,除非您将它们从基类转换回实现类。

    【讨论】:

    • 非常感谢!这一点,再加上其他回应肯定会帮助我度过难关:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多