接口扩展方法在实现中不可见 类
Interface extension methods not visible on implementation classes
我定义了一个"type translator"接口(请不要提及AutoMapper,不相关)如下:
public interface ITranslator<TSource, TResult>
{
TResult Translate(TSource source);
}
为了方便起见,我定义了一个可枚举的扩展方法:
public static class ExtendITranslator
{
public static IEnumerable<TResult> TranslateSet<TSource, TResult>(
this ITranslator<TSource, TResult> self,
IEnumerable<TSource> sourceSet)
{
return sourceSet.Select(o => self.Translate(o));
}
}
然后我这样定义实现:
public class Translator :
ITranslator<Report, Report.ReportServiceModel>,
ITranslator<Report.ReportServiceModel, Report>
{
public Report Translate(Report.ReportServiceModel source)
{
throw new NotImplementedException();
}
public Report.ReportServiceModel Translate(Report source)
{
throw new NotImplementedException();
}
}
问题是,当我使用 Translator
实现时,它不会将 TranslateSet
公开为扩展方法,除非我强制转换:
Translator translator = new Translator();
// not exposed
translator.TranslateSet(/* ... */);
// exposed with a cast
(translator as ITranslator<Report, Report.ReportServiceModel>).TranslateSet(/* ... */);
这是为什么?其他class实现公开了为它们实现的接口定义的扩展方法:
public interface IUpdater<TModel> where TModel : class, new()
{
bool Update(TModel model);
}
public static class ExtendIRepositoryWriter
{
public static int UpdateSet<TModel>(
this IRepositoryWriter<TModel> self,
IEnumerable<TModel> modelSet) where TModel : class, new()
{
return modelSet.Count(o => self.Update(o));
}
}
public class ReportUpdater : IUpdater<Report>
{
public bool Update(Report model)
{
throw new NotImplementedException();
}
}
在这种情况下,UpdateSet
扩展方法可用于 ReportUpdater
的实例:
ReportUpdater reportUpdater = new ReportUpdater();
// all good!
reportUpdater.UpdateSet(/* ... */);
任何人都可以阐明这一点吗?我是不是打错了字或什么的? (毕竟是星期五晚上)
您的其他工作示例实际上具有误导性,并不是真正的同类比较。
由于单个泛型参数,编译器能够推断类型,因为您正在调用该类型的实例。
扩展给您带来的麻烦不是这种情况,因为有两个类型参数。您可以通过将具体类型分配给声明类型的接口来解决此问题。
ITranslator<Report, Report.ReportServiceModel> translator = new Translator();
translator.TranslateSet(/* ... */);
我定义了一个"type translator"接口(请不要提及AutoMapper,不相关)如下:
public interface ITranslator<TSource, TResult>
{
TResult Translate(TSource source);
}
为了方便起见,我定义了一个可枚举的扩展方法:
public static class ExtendITranslator
{
public static IEnumerable<TResult> TranslateSet<TSource, TResult>(
this ITranslator<TSource, TResult> self,
IEnumerable<TSource> sourceSet)
{
return sourceSet.Select(o => self.Translate(o));
}
}
然后我这样定义实现:
public class Translator :
ITranslator<Report, Report.ReportServiceModel>,
ITranslator<Report.ReportServiceModel, Report>
{
public Report Translate(Report.ReportServiceModel source)
{
throw new NotImplementedException();
}
public Report.ReportServiceModel Translate(Report source)
{
throw new NotImplementedException();
}
}
问题是,当我使用 Translator
实现时,它不会将 TranslateSet
公开为扩展方法,除非我强制转换:
Translator translator = new Translator();
// not exposed
translator.TranslateSet(/* ... */);
// exposed with a cast
(translator as ITranslator<Report, Report.ReportServiceModel>).TranslateSet(/* ... */);
这是为什么?其他class实现公开了为它们实现的接口定义的扩展方法:
public interface IUpdater<TModel> where TModel : class, new()
{
bool Update(TModel model);
}
public static class ExtendIRepositoryWriter
{
public static int UpdateSet<TModel>(
this IRepositoryWriter<TModel> self,
IEnumerable<TModel> modelSet) where TModel : class, new()
{
return modelSet.Count(o => self.Update(o));
}
}
public class ReportUpdater : IUpdater<Report>
{
public bool Update(Report model)
{
throw new NotImplementedException();
}
}
在这种情况下,UpdateSet
扩展方法可用于 ReportUpdater
的实例:
ReportUpdater reportUpdater = new ReportUpdater();
// all good!
reportUpdater.UpdateSet(/* ... */);
任何人都可以阐明这一点吗?我是不是打错了字或什么的? (毕竟是星期五晚上)
您的其他工作示例实际上具有误导性,并不是真正的同类比较。
由于单个泛型参数,编译器能够推断类型,因为您正在调用该类型的实例。
扩展给您带来的麻烦不是这种情况,因为有两个类型参数。您可以通过将具体类型分配给声明类型的接口来解决此问题。
ITranslator<Report, Report.ReportServiceModel> translator = new Translator();
translator.TranslateSet(/* ... */);