DIl*_*d K 5 .net c# generics reflection mef
我有一些类和接口:
interface IAnimal { }
interface ILiveInZoo { }
class Cat : IAnimal, ILiveInZoo { }
Run Code Online (Sandbox Code Playgroud)
另外,我有一些方法和通用方法:
class Context
{
private static CompositionContainer Container = null;
public ILiveInZoo GetWhoLivesInZoo(string name)
{
if (name == "Cat")
return new Cat();
return null;
}
public void GiveFood<T>(T animal) where T : IAnimal
{
var methods = Container.GetExports<Action<T, EventArgs>, AttributeMetadata>();
//execute methods
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个用例:
Context context = new Context();
var cat = context.GetWhoLivesInZoo("Cat");
if (cat is IAnimal animal)
{
context.GiveFood(animal);
}
Run Code Online (Sandbox Code Playgroud)
如您在GiveFoodmetod 中所见,我正在使用MEF。在使用情况下,当我投cat来IAnimal,在GiveFood法typeof(T)会IAnimal不会Cat。第一个问题是:cat变量的实例是Cat类。为什么当我投放时typeof(T)会成为IAnimal?我的问题是,当我投cat来IAnimal界面,GiveFood方法,GetExports相关方法返回方法IAnimal不Cat类。我找到解决此问题的解决方案,它使用反射:
Context context = new Context();
var cat = context.GetWhoLivesInZoo("Cat");
if (cat is IAnimal animal)
{
MethodInfo method = typeof(Context).GetMethod(nameof(Context.GiveFood));
MethodInfo generic = method.MakeGenericMethod(animal.GetType());
generic.Invoke(context, new object[] { animal });
}
Run Code Online (Sandbox Code Playgroud)
现在typeof(T)是Cat类,GiveFood我可以得到与Cat类相关的方法。是否有另一种方法(不使用反射)来解决此问题?
小智 0
一个简单易用的解决方案可能是使用动态:
Context context = new Context();
var cat = context.GetWhoLivesInZoo("Cat");
if (cat is IAnimal animal)
{
context.GiveFood((dynamic)animal);
}
Run Code Online (Sandbox Code Playgroud)
但请注意,它dynamic在内部使用反射(通过缓存来提高性能)。因此,如果您真的想避免反射,另一个答案中描述的访问者模式可能是正确的选择。