简体   繁体   English

接口扩展方法在实现类上不可见

[英]Interface extension methods not visible on implementation classes

I've defined a "type translator" interface (please don't mention AutoMapper, not relevant) as follows:我已经定义了一个“类型翻译器”接口(请不要提及 AutoMapper,不相关)如下:

public interface ITranslator<TSource, TResult>
{
    TResult Translate(TSource source);
}

And for convenience sake, I've defined an extension method for enumerables:为方便起见,我为可枚举定义了一个扩展方法:

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

And then I define the implementation as so:然后我将实现定义为:

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

The problem is, when I work with the Translator implementation, it doesn't expose TranslateSet as an extension method, unless I cast:问题是,当我使用Translator实现时,它不会将TranslateSet作为扩展方法公开,除非我强制转换:

Translator translator = new Translator();

// not exposed
translator.TranslateSet(/* ... */);

// exposed with a cast
(translator as ITranslator<Report, Report.ReportServiceModel>).TranslateSet(/* ... */);

Why is this?为什么是这样? Other class implementations expose extension methods defined for the interfaces they implement:其他类实现公开为它们实现的接口定义的扩展方法:

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

In this case, the UpdateSet extension method is available on instances of ReportUpdater :在这种情况下, UpdateSet扩展方法可用于ReportUpdater实例:

ReportUpdater reportUpdater = new ReportUpdater();

// all good!
reportUpdater.UpdateSet(/* ... */);

Can anyone shed some light on this?任何人都可以对此有所了解吗? Did I fat-finger a typo or something?我胖了一个错字还是什么? (It is Friday night after all) (毕竟是周五晚上)

Your other working example is actually misleading and is not a true apples-to-apples comparison.您的另一个工作示例实际上具有误导性,并且不是真正的苹果对苹果的比较。

Due to a single generic argument, the compiler is able to infer the type since you are invoking on an instance of that type.由于单个泛型参数,编译器能够推断类型,因为您正在调用该类型的实例。

This is not the case with the extension giving you trouble, since there are two type arguments.扩展程序不会给您带来麻烦,因为有两种类型参数。 You can resolve this by assigning the concrete type to an interface declaring the types.您可以通过将具体类型分配给声明类型的接口来解决此问题。

ITranslator<Report, Report.ReportServiceModel> translator = new Translator();

translator.TranslateSet(/* ... */);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM