アプローチ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)));
}
アプローチ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)));
}
アップデート
重要
これらのアプローチは両方とも、ランタイムチェックのみを提供します。コンパイルチェックの実装がある方が良いでしょうが、それを達成する方法がわからないのです。
UPDATE2
動的登録の場合:
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;
}
}
PS2、などの
メソッドが実装されていないことをお詫びします。現在のマシンにはまだVisual Studioがなく、APIを正確に覚えていません。MarkedByAttribute
IsDerivedFrom
ImplementsInterface