我确定以前曾经问过这个问题,但我似乎无法找到我想要的解决方案,尽管SO / Google搜索很长,所以希望你能回答我的问题
为简洁起见,我们假设我有以下对象:
$(".gallery").load(value +".html", showThem);
现在我的控制器中有以下代码:
public interface ISectionView { }
public class SampleSectionView : ISectionView { }
public interface ISectionService<T> where T : ISectionView { }
public class SampleSectionService : ISectionService<SampleSectionView>
出于此目的,_serviceResolver.Resolve方法如下所示:
ISectionView sectionType = new SampleSectionView(); // *** NOTE THE TYPE
var service = _serviceResolver.Resolve(sectionType);
因此,正如我们上面所看到的,我在控制器中创建了sectionType变量作为ISectionView类型,SampleSectionView实现了该类型。这导致我在resolve方法中出现问题,因为它实际上正在做的事情(因为我在立即窗口中检查了这一点)如下:
public ISectionService<V> Resolve<V>(V sectionViewModel)
where V : ISectionView
{
var sectionViewModelTypeName = sectionViewModel.GetType().Name;
// Ignore this, it's some AutoFac metadata resolution
var resolvableService = _services.FirstOrDefault(s => s.Matches(sectionViewModelTypeName));
if (resolvableService != null)
return resolvableService.Value as ISectionService<V>; // Upcast, as this is the actual type we want!
return null;
}
这是一个问题,因为我的服务想要转换为以下内容:
return resolvableService.Value as ISectionService<ISectionView>;
我知道我已将SampleSectionView对象传递给此resolve方法,但基于通用V类型参数的转换有点丢失。
那么我怎样才能让演员认识到实际的具体类型,而不是它下面创建的接口类型?
为了记录,我知道我可以做到以下几点:
return resolvableService.Value as ISectionService<SampleSectionView>;
但这是一个问题,因为我需要一个Factory方法来创建ISectionView,所以我知道这是我传入Resolve的类型。是的,我可以看出为什么这是一个问题,那么可以做些什么来克服这个问题呢?如果可能的话,我宁愿不有一个switch / case语句来处理转换。
谢谢
感谢所有评论。最后,我所要做的就是将ISectionService接口修改为以下内容:
var sectionType = new SampleSectionView();
这就足够了。
答案 0 :(得分:1)
接口不能以这种方式工作,唯一可以将接口IInterface<IBase>
强制转换为IInterface<IDerived>
的方法是使用out
参数声明接口。
我建议您阅读question中的答案。我相信它会为您提供所需的信息。
答案 1 :(得分:1)
我不确定这是最好的解决方案,但你可以将它包装成带有反射的非泛型方法。
class ServiceResolver
{
public ISectionService<ISectionView> ResolveNonGeneric(ISectionView sectionViewModel)
{
var method = GetType()
.GetMethod(nameof(Resolve), BindingFlags.Public | BindingFlags.Instance)
.MakeGenericMethod(sectionViewModel.GetType());
return (ISectionService<ISectionView>) method.Invoke(this, new[] { sectionViewModel });
}
public ISectionService<V> Resolve<V>(V sectionViewModel) where V : ISectionView
{
//V is SampleSectionView
}
}
从而执行:
ISectionView sectionType = new SampleSectionView();
var service = _serviceResolver.ResolveNonGeneric(sectionType);
将在内部执行Resolve<SampleSectionView>
。
这需要制作ISectionService<T>
协变。