简体   繁体   English

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

[英]Call 3rd-party assembly's overloaded method from generic method using dynamic (or by other means)?

Update: Turns out there were details I had completely missed until I looked at the source code of the library I was using. 更新:事实证明,在查看所使用的库的源代码之前,我已经完全错过了细节。 Apologies for the bad example code starting out, was trying to focus on what I thought was relevant. 不好的示例代码开始的道歉,是在试图专注于我认为相关的内容。

Working with FlatFiles NuGet library which has 25 overloads for a Property(...) method. 使用FlatFiles NuGet库,该库的Property(...)方法有25个重载。 I'm trying to dispatch the correct Property(...) overload from my generic method by using dynamic on a parameter I'm passing, but this isn't working. 我正在尝试通过对要传递的参数使用dynamic来从通用方法中调度正确的Property(...)重载,但这无法正常工作。 Here's what I tried: 这是我尝试过的:

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

A few of the Property overloads: 一些属性重载:

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

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

Looking at the source I see the there's an internal sealed class FixedLengthTypeMapper<TEntity> and this is the type of object that's being returned from the call to FixedLengthTypeMapper.Define<FixedWidthRecordT>() and assigned to Mapper . 查看源代码,我看到有一个internal sealed class FixedLengthTypeMapper<TEntity> ,这是从对FixedLengthTypeMapper.Define<FixedWidthRecordT>()的调用返回并分配给Mapper的对象的类型。 However, IFixedLengthTypeMapper does not have any definitions for Property(...) , only FixedLengthTypeMapper has them. 但是, IFixedLengthTypeMapper没有Property(...)任何定义,只有FixedLengthTypeMapper拥有它们。

Hoping that's all relevant. 希望这一切都是相关的。

Maybe your case has something to do with this? 也许您的情况与此有关? RuntimeBinderException – “does not contain a definition for” . RuntimeBinderException –“不包含”的定义

That article gets that exception in the case of an anonymous object, but your case seems similar. 在匿名对象的情况下,该文章将获得该例外,但您的情况似乎很相似。 Your assembly is trying to access something through dynamic it cannot normally see: an internal class in your case, an anonymous type in theirs. 您的程序集试图通过dynamic方式访问它通常看不到的东西:您的情况下为internal类,而internal类为匿名类型。

Adding the [assembly: InternalsVisibleTo("Your.Assembly")] attribute on the library doesn't sound like a good option, but if you can build from source it could help temporarily. 在库中添加[assembly: InternalsVisibleTo("Your.Assembly")]属性听起来不是一个好选择,但是如果您可以从源代码构建它可能会暂时提供帮助。 Or maybe with that info you could create a solid repro. 或者,也许您可​​以利用该信息来创建可靠的副本。

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). 我仍然很好奇如何解决此问题(例如,如果我在解决方案中使用的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);

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

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