使用动态(或通过其他方式)从泛型方法调用 3rd 方程序集的重载方法?
Call 3rd-party assembly's overloaded method from generic method using dynamic (or by other means)?
更新:原来我完全错过了一些细节,直到我查看了我正在使用的库的源代码。为糟糕的示例代码道歉,试图专注于我认为相关的内容。
使用 FlatFiles NuGet 库,它有 25 个 Property(...)
方法重载。我正在尝试通过对传递的参数使用 dynamic 从我的泛型方法中分派正确的 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 – “does not contain a definition for”.
那篇文章在匿名对象的情况下得到了那个例外,但你的情况似乎相似。您的程序集正试图通过 dynamic
访问它通常看不到的东西:在您的情况下是 internal
class,在他们的情况下是匿名类型。
在库中添加 [assembly: InternalsVisibleTo("Your.Assembly")]
属性听起来不是一个好的选择,但如果您可以从源代码构建它可能会暂时有所帮助。或者也许有了这些信息,您可以创建可靠的复制品。
这是我最终使它工作的方法,尽管它是通过使用库的使用文档中未描述的接口。我仍然很好奇如何解决这个问题(例如,如果我在解决方案中使用的 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);
更新:原来我完全错过了一些细节,直到我查看了我正在使用的库的源代码。为糟糕的示例代码道歉,试图专注于我认为相关的内容。
使用 FlatFiles NuGet 库,它有 25 个 Property(...)
方法重载。我正在尝试通过对传递的参数使用 dynamic 从我的泛型方法中分派正确的 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 – “does not contain a definition for”.
那篇文章在匿名对象的情况下得到了那个例外,但你的情况似乎相似。您的程序集正试图通过 dynamic
访问它通常看不到的东西:在您的情况下是 internal
class,在他们的情况下是匿名类型。
在库中添加 [assembly: InternalsVisibleTo("Your.Assembly")]
属性听起来不是一个好的选择,但如果您可以从源代码构建它可能会暂时有所帮助。或者也许有了这些信息,您可以创建可靠的复制品。
这是我最终使它工作的方法,尽管它是通过使用库的使用文档中未描述的接口。我仍然很好奇如何解决这个问题(例如,如果我在解决方案中使用的 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);