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

本文关键字:第三方 调用 泛型方法 程序集 方法 重载 动态 方式 其他 | 更新日期: 2023-09-27 18:04:53

更新:原来有一些细节我完全错过了,直到我查看了我正在使用的库的源代码。

与FlatFiles NuGet库一起工作,该库有25个重载的Property(...)方法。我试图通过在我传递的参数上使用动态来从我的通用方法调度正确的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有。

希望这些都是相关的

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

也许你的情况与此有关?RuntimeBinderException - "不包含"的定义。

那篇文章在匿名对象的情况下得到了该异常,但您的情况似乎类似。您的程序集正试图通过dynamic访问它通常无法看到的东西:在您的情况下是internal类,在他们的情况下是匿名类型。

在库上添加[assembly: InternalsVisibleTo("Your.Assembly")]属性听起来不像是一个好选择,但如果您可以从源代码构建,它可能会暂时有所帮助。或者你可以用这些信息创建一个实体的reppro

这是我最终使它工作的方法,尽管它使用了库使用文档中没有描述的接口。我仍然很好奇这是如何解决的(例如,如果我在解决方案中使用的IFixedLengthTypeConfiguration接口也被定义为内部)。

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