Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 灵活的课堂设计,遵循开闭原则_C#_Oop_Design Patterns - Fatal编程技术网

C# 灵活的课堂设计,遵循开闭原则

C# 灵活的课堂设计,遵循开闭原则,c#,oop,design-patterns,C#,Oop,Design Patterns,我正在玩一些应用程序,并进行一些重构,以使其更加灵活。正如我所料,出现了很多问题。 例如,我正试图找到一种最佳的方法来删除太空船级集合中的项目 class Spaceship{ List<Weapon> Weapons {get;set;} List<Shield> Shields {get;set;} public void RemoveEquipment(Equipment item){ switch(item.EquipmentType ) { c

我正在玩一些应用程序,并进行一些重构,以使其更加灵活。正如我所料,出现了很多问题。 例如,我正试图找到一种最佳的方法来删除太空船级集合中的项目

class Spaceship{
 List<Weapon> Weapons {get;set;}
 List<Shield> Shields {get;set;}

 public void RemoveEquipment(Equipment item){
 switch(item.EquipmentType )
 {
   case EquipmentType.Weapon:
     weapons.Remove(item);
     break;
   case EquipmentType.Shield:
     shields.Remove(item);
     break;
 }    
 }

 public void AddEquipment(Equipment item){
 //works the same way as RemoveEquipment
 }

}

class Equipment{    
 //EquipmentType is enum
 EquipmentType Type {get;set;};
}

class Weapon: Equipment{    
}

class Shield:Equipment{
}

class AutoCannon:Weapon{
}

class LaserGun:Weapon {

}
级宇宙飞船{
列出武器{get;set;}
列表屏蔽{get;set;}
公共无效清除设备(设备项){
开关(项目.设备类型)
{
箱子装备类型。武器:
武器。移除(项目);
打破
外壳设备类型。屏蔽:
屏蔽。移除(项目);
打破
}    
}
公用设备(设备项){
//与RemoveeEquipment的工作方式相同
}
}
类设备{
//设备类型为enum
EquipmentType类型{get;set;};
}
武器类别:装备{
}
防护等级:设备{
}
自动驾驶舱:武器{
}
激光枪:武器{
}
有更好的办法吗?如果我想删除相同子类型的一组项目(例如,武器收藏中的每个激光枪-不使用反射),该怎么办
如果我想添加新类型的设备,则必须修改负责添加/删除的方法(开关/案例)

根据经验,您不希望公开类型为
List
的属性,尤其是如果它们不是只读的。我建议将
武器
盾牌
属性更改为
IEnunerable
或至少
IReadOnlyList
,并将其设置为只读

话虽如此,您的
太空船
类可以如下所示:

// internal is the default access modifier for types, but it's more descriptive to specify it. 
internal class Spaceship
{

    private List<Equipment> _equipment = new List<Equipment>();

    public IEnumerable<Weapon> Weapons {get {return _equipment.OfType<Weapon>();}}
    public IEnumerable<Shield> Shields {get {return _equipment.OfType<Shield>();}}

    public void RemoveEquipment(Equipment item)
    {
        _equipment.Remove(item);
    }

    public void AddEquipment(Equipment item)
    {
        _equipment.Add(item);
    }

}
public void RemoveEquipment<T>() where T : Equipment
{
    _equipment.RemoveAll(e => e is T);
}
//internal是类型的默认访问修饰符,但指定它更具描述性。
内舱宇宙飞船
{
私有列表_设备=新列表();
公共IEnumerable武器{get{return_equipment.OfType();}}
公共IEnumerable Shields{get{return{u equipment.OfType();}}
公共无效清除设备(设备项)
{
_设备。移除(项目);
}
公用设备(设备项)
{
_设备。添加(项目);
}
}
然后,为了移除特定类型的所有设备,您可以执行以下操作:

// internal is the default access modifier for types, but it's more descriptive to specify it. 
internal class Spaceship
{

    private List<Equipment> _equipment = new List<Equipment>();

    public IEnumerable<Weapon> Weapons {get {return _equipment.OfType<Weapon>();}}
    public IEnumerable<Shield> Shields {get {return _equipment.OfType<Shield>();}}

    public void RemoveEquipment(Equipment item)
    {
        _equipment.Remove(item);
    }

    public void AddEquipment(Equipment item)
    {
        _equipment.Add(item);
    }

}
public void RemoveEquipment<T>() where T : Equipment
{
    _equipment.RemoveAll(e => e is T);
}
public void RemoveEquipment(),其中T:设备
{
_设备拆除(e=>e为T);
}
您还可以同时添加一组设备:

public void AddEquipment(IEnumerable<Equipment> items)
{
    _equipment.AddRange(items);
}
public void AddEquipment(IEnumerable items)
{
_设备。添加范围(项目);
}
请注意,并没有更麻烦的开关语句,也几乎并没有涉及特定类型的设备——除非你们明确需要盾牌和武器


当然,主要的好处是,当添加一种新型装备时,你不需要改变你的
太空船
类来支持它(当然,除非你想拥有一个专门用于该特定类型装备的属性,如
武器
盾牌
).

你真的需要有
武器
盾牌
设定器吗?如果您可以使这些属性成为只读属性,那么就可以轻松地使用泛型来生成更好、更短的代码。另外,一艘船可以有多种武器或盾牌吗?因为如果可以,那么这些属性应该是
IEnumerable
IEnumerable
而不是单个
武器或
盾牌。我错了,这些属性是集合