使用动态(或通过其他方式)从泛型方法调用第三方程序集的重载方法?

时间:2015-07-27 20:34:24

标签: c# generics dispatch overload-resolution

更新:在我查看我正在使用的库的源代码之前,我完全错过了详细信息。对于糟糕的示例代码开始道歉,他们试图关注我认为相关的内容。

使用FlatFiles NuGet库,它对Property(...)方法有25次重载。我试图通过在我传递的参数上使用动态来从我的泛型方法调度正确的Property(...)重载,但这不起作用。这是我试过的:

using FlatFiles;
using FlatFiles.TypeMapping;

public class FixedWidthDataSource<FixedWidthRecordT> {
    public IFixedLengthTypeMapper<FixedWidthRecordT> Mapper
        = FixedLengthTypeMapper.Define<FixedWidthRecordT>()
    ;
    ...
    public void MapProperty<T>(
        Expression<Func<FixedWidthRecordT, T>> col
        , int width
        , string inputFormat = null
    ) {
        var window = new Window(width);
        Mapper.Property((dynamic)col, window);
    }
}

public class FixedWidthRecord
{
    public string First { get; set; }
    public string Last { get; set; }
}

//later
var fwds = new FixedWidthDataSource<FixedWidthRecord>();
fwds.MapProperty(c=>c.First, 5);

一些属性重载:

Property(Expression<Func<FixedWidthRecordT, bool>> property, Window window);
Property(Expression<Func<FixedWidthRecordT, int>> property, Window window);
Property(Expression<Func<FixedWidthRecordT, string>> property, Window window);

我得到的错误是'FlatFiles.TypeMapping.IFixedLengthTypeMapper<FixedWidthRecord>' does not contain a definition for 'Property'

看看来源,我看到有一个 internal sealed class FixedLengthTypeMapper<TEntity> 这是从FixedLengthTypeMapper.Define<FixedWidthRecordT>()的调用返回并分配给Mapper的对象类型。但是,IFixedLengthTypeMapper没有Property(...)的任何定义,只有FixedLengthTypeMapper拥有它们。

希望这一切都是相关的。

2 个答案:

答案 0 :(得分:1)

也许你的情况与此有关? RuntimeBinderException – “does not contain a definition for”

该文章在匿名对象的情况下获得该异常,但您的情况似乎相似。你的程序集正试图通过dynamic访问某些内容,它通常看不到:你的internal类,他们的匿名类型。

在库中添加[assembly: InternalsVisibleTo("Your.Assembly")]属性听起来不是一个好选择,但是如果你可以从源代码构建它可以暂时帮助。或者也许有了这些信息,你可以创建一个坚实的复制品。

答案 1 :(得分:1)

Here is what I finally did to get it working, although it's by using an interface not described in the library's usage documentation. I'm still curious how this could have otherwise been solved (say for instance, if the IFixedLengthTypeConfiguration interface I'm using in the solution were also defined as internal).

using FlatFiles;
using FlatFiles.TypeMapping;

public class FixedWidthDataSource<FixedWidthRecordT> {
    public IFixedLengthTypeConfiguration<FixedWidthRecordT> Configuration
        = FixedLengthTypeMapper.Define<FixedWidthRecordT>()
    ;
    public IFixedLengthTypeMapper<FixedWidthRecordT> Mapper;
    public FixedWidthDataSource() {
        Mapper = (IFixedLengthTypeMapper<FixedWidthRecordT>)Configuration;
    }
    ...
    public void MapProperty<T>(
        Expression<Func<FixedWidthRecordT, T>> col
        , int width
        , string inputFormat = null
    ) {
        var window = new Window(width);
        Configuration.Property((dynamic)col, window);
    }
}

public class FixedWidthRecord
{
    public string First { get; set; }
    public string Last { get; set; }
}

//later
var fwds = new FixedWidthDataSource<FixedWidthRecord>();
fwds.MapProperty(c=>c.First, 5);