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;
}
}