Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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_List_Inheritance - Fatal编程技术网

C# 我可以拿一份清单吗<&燃气轮机;同一子体的对象类型?

C# 我可以拿一份清单吗<&燃气轮机;同一子体的对象类型?,c#,oop,list,inheritance,C#,Oop,List,Inheritance,我需要保存允许执行某些操作的对象类型的列表 例动物有3个后代老虎,人类,河马 我只想把老虎和河马关在动物园的笼子里?我需要一份动物种类的清单 我想要比列表更好的东西 这只是一个简单的例子。我不喜欢笼子里的动物 编辑 因为还不清楚。我希望在列表中保留对象类型,而不是实际对象 例如: List<Type> types = new List<Type>(); types.Add(typeof(Hippo)); types.Add(typeof(Tiger)); 列表类型=新列

我需要保存允许执行某些操作的对象类型的列表

动物
有3个后代
老虎
人类
河马

我只想把老虎和河马关在动物园的笼子里?我需要一份动物种类的清单

我想要比列表更好的东西

这只是一个简单的例子。我不喜欢笼子里的动物

编辑

因为还不清楚。我希望在列表中保留对象类型,而不是实际对象

例如:

List<Type> types = new List<Type>();
types.Add(typeof(Hippo));
types.Add(typeof(Tiger));
列表类型=新列表();
类型。添加(类型(河马));
类型。添加(类型(老虎));
这是程序员可以做的
types.Add(typeof(Human))
的限制,这是我不允许的

edit2


只是想澄清我的问题。我希望能够动态地
注册
允许的类型,而不必像下面的一些答案那样有后续的
if
s。

如果您只需要特定类型的列表:

泛型中没有任何东西可以支持您的请求,因此只需创建一个自定义类型,允许您存储
type
类型,并在运行时使用代码来防止无效条目:

public class CagedTypes 
{
    private readonly List<Type> _types;

    public void Add(Type t)
    {
        if (t == typeof(Hippo) || t == typeof(Tiger))
            _types.Add(t);
    }
}
您还可以使用属性,因为您可以使用
GetAttributes
方法查询任何属性的类型

如果希望列表中只包含某些实例:

创建标记接口:

public interface ICanBeHeldInZooCage
Tiger
Hippo
工具(不需要做任何事情),那么你可以有:

var cagedAnimals = new List<ICanBeHeldInZooCage>();
var cagedAnimals=newlist();
人是动物,老虎是应该在动物园里的动物。因此,在您的例子中,我将为
Tiger
Hippo
再创建一个基类

public class AnimalInZoo : Animal {}
public class Tiger : AnimalInZoo {}
public class Hippo : AnimalInZoo {}
public class Human : Animal {}
您可以创建助手函数
AddInZoo(AnimalInZoo obj)
以添加到您的
List m_Zoo

void AddInZoo(AnimalInZoo obj)
{
    m_Zoo.Add(obj.GetType());
}

界面怎么样

public interface ICageable {}

public abstract class Animal {}

public class Hippo : Animal, ICageable {}

public class Tiger : Animal, ICageable {}

public class Human : Animal, ICageable {}

public class Ape : Animal {}

....
List<ICageable> ZooAnimals = new List<ICageable>{hippo, tiger, human};

我会使用一个界面来确定一个动物是否是动物

  public class Animal
  {
    public string Name;
  }
  public class Tiger : Animal, IZooAnimal
  {

  }
  public class Human : Animal
  {

  }
  public interface IZooAnimal
  {
    //Some zoo animal properties
  }
然后检查该动物是否是动物园动物
如果(a是IZooAnimal)
下面是您可以使用的动物园类

  public class Zoo
  {
    public List<IZooAnimal> AnimalsInZoo = new List<IZooAnimal>();
    public void AddAnimal(IZooAnimal a)
    {
      AnimalsInZoo.Add(a);
    }
  }
这将把
type
老虎添加到
AnimalsInZoo
。希望这对你有用

  Zoo<IZooAnimal> cage = new Zoo<IZooAnimal>();
  cage.AddType(typeof(Tiger));
  cage.AddType(typeof(Human));
Zoo-cage=new-Zoo();
cage.AddType(typeof(Tiger));
cage.AddType(typeof(Human));
另一个选项:

public abstract class Animal
{
    public abstract bool IsCagable { get; }
}
并让嵌套类实现它们的行为

随后,在Add方法中,本主题答案中主要介绍的某种
Zoo
类必须进行检查:

public sealed class ZooList : List<Animal> // I believe you need Animal, not Type
{
    // ... some implementations ...

    public override sealed void Add(Animal animal)
    {
        if (!animal.IsCagable)
            // Prevent from adding.
    }
}
public sealed class ZooList:List//我相信你需要的是动物,而不是类型
{
//…一些实现。。。
公共覆盖密封无效添加(动物)
{
如果(!animal.IsCagable)
//防止添加。
}
}

方法1-通过接口:

public interface ICageable
{ }

public abstract class Animal
{}

public class Hippo : Animal, ICageable
{}

public class Human : Animal, ICageable
{}

public IEnumerable<Type> GetCageableAnimals()
{
    return  GetAssemblyTypes(assembly:typeof(Animal).Assembly)
        .Where(type=>IsDerivedFrom(type, typeof(Animal)))
        .Where(type=>ImplementsInterface(type,typeof(ICageable)));
}
公共接口可兼容
{ }
公共抽象类动物
{}
公共级河马:动物,可食
{}
公共类人类:动物,可移植
{}
公共IEnumerable GetCageable动物()
{
return GetAssemblyTypes(程序集:typeof(Animal).assembly)
其中(type=>IsDerivedFrom(type,typeof(动物)))
其中(type=>ImplementsInterface(type,typeof(ICageable));
}
方法2-通过属性:

public class InCageAttribute : Attribute
{ }

public abstract class Animal
{}

[InCage]
public class Hippo : Animal
{}

public class Human : Animal
{}

public IEnumerable<Type> GetCageableAnimals()
{
    return  GetAssemblyTypes(assembly:typeof(Animal).Assembly)
        .Where(type=>IsDerivedFrom(type, typeof(Animal)))
        .Where(type=>MarkedByAttribute(type,typeof(InCageAttribute)));
}
公共类InCageAttribute:属性
{ }
公共抽象类动物
{}
[印加]
公营河马:动物
{}
公共类人:动物
{}
公共IEnumerable GetCageable动物()
{
return GetAssemblyTypes(程序集:typeof(Animal).assembly)
其中(type=>IsDerivedFrom(type,typeof(动物)))
其中(type=>MarkedByAttribute(type,typeof(InCageAttribute)));
}
更新

重要

这两种方法都只提供运行时检查。有编译检查实现会更好,但不知道如何实现

更新2
对于动态注册:

public class CageRegistry
{
    private List<Type> _allowedTypes = new List<Type>();
    public IEnumerable<Type> AllowedTypes{get{return _allowedTypes;}}

    public bool TryAdd(Type type)
    {
        if(ImplementsInterface(type, typeof(ICageable)))// for approach with attributes code is pretty similar
        {
            _allowedTypes.Add(type);
            return true;
        }
        return false;
    }
}
公共类注册表
{
私有列表_allowedTypes=新列表();
public IEnumerable AllowedTypes{get{return}\u AllowedTypes;}
公共bool TryAdd(类型)
{
if(ImplementsInterface(type,typeof(ICageable))//对于带有属性的方法,代码非常相似
{
_allowedTypes.Add(类型);
返回true;
}
返回false;
}
}
PS2

很抱歉,没有实现像
MarkedByAttribute
isderived from
ImplementsInterface
这样的方法-我只是在当前机器上还没有visual studio,也记不清api。

我想只允许老虎和河马被关在动物园的笼子里
这对我来说太寓言了。你能给出一个你想做什么的代码示例吗?我想你可以有动物的ZooAnimal后代,从中只继承老虎和河马,然后有列表?列表有什么问题?列表中允许任何类型。我想限制that@Veli我不需要对象实例,但需要list@AgentFire谢谢-对我自己来说太快了,为什么我想传递一个动物并将其施放,而不是在构造函数中只接受一个
izooamal
,我永远都不知道@LukeHannerley我想要保存对象类型,而不是对象instances@odyodyodys因此,在
列表中
您想要保存一个
列表
,您永远不想保存实例?将
公共类动物园中的T:IZooAnimal
更改为
公共类动物园
if(typeof(T)==a)
更改为
if(a.IsAssignableFrom(IZooAnimal))
我想保存对象
类型
s,而不是对象实例。这在题目和正文中都很清楚。我不明白为什么这是一个有投票权的答案。@odyodyodys:添加了类型的东西,s
public interface ICageable
{ }

public abstract class Animal
{}

public class Hippo : Animal, ICageable
{}

public class Human : Animal, ICageable
{}

public IEnumerable<Type> GetCageableAnimals()
{
    return  GetAssemblyTypes(assembly:typeof(Animal).Assembly)
        .Where(type=>IsDerivedFrom(type, typeof(Animal)))
        .Where(type=>ImplementsInterface(type,typeof(ICageable)));
}
public class InCageAttribute : Attribute
{ }

public abstract class Animal
{}

[InCage]
public class Hippo : Animal
{}

public class Human : Animal
{}

public IEnumerable<Type> GetCageableAnimals()
{
    return  GetAssemblyTypes(assembly:typeof(Animal).Assembly)
        .Where(type=>IsDerivedFrom(type, typeof(Animal)))
        .Where(type=>MarkedByAttribute(type,typeof(InCageAttribute)));
}
public class CageRegistry
{
    private List<Type> _allowedTypes = new List<Type>();
    public IEnumerable<Type> AllowedTypes{get{return _allowedTypes;}}

    public bool TryAdd(Type type)
    {
        if(ImplementsInterface(type, typeof(ICageable)))// for approach with attributes code is pretty similar
        {
            _allowedTypes.Add(type);
            return true;
        }
        return false;
    }
}