[英]Can not get instance of type derived in F# library correctly
我的项目在 C# 库中使用 F# 的类型时遇到问题。
我有一个基本上由以下主要部分组成的应用程序:
核心库包含所有与平台无关的逻辑和视图模型,可用于任何类型的 UI 客户端。 该应用程序被设计为可扩展的,并且可以在加载 UI 之前动态插入扩展。 现在它只是通过Assembly.LoadFrom从特定文件夹加载DLL 。 将dll识别为扩展的唯一要求是公开派生自核心库中定义的模块或扩展类的特殊类。 在加载用 C# 编写的程序集时,它工作得很好。 但是当我尝试使用用 F# 编写的扩展时,我遇到了非常奇怪的行为。 假设我有一个在我的核心库中定义的接口IRecognitionProcessor 。 以下是它的一些成员:
public interface IRecognitionProcessor
{
string Name { get; }
string Description { get; }
bool ContainsFace(Bitmap bitmap);
FaceDetail[] ExtractDetails(Bitmap bitmap);
/* more members goes here */
}
在我为 .NET 提供基于EmguCV库的自定义识别的新扩展中,我有一个IRecognitionProcessor的后代,结果将被提取并存储在特殊容器中。 正如我之前提到的,该扩展是用 F# 编写的。 这是实现的一个简短示例:
type EmguFaceRecognition() =
interface IRecognitionProcessor with
member this.Name : string = "EmguCV"
member this.Description : string = "EmguCV face recognition processor"
member this.ContainsFace (bitmap : Bitmap) : bool =
//code goes here
member this.ExtractDetails (bitmap : Bitmap) : FaceDetail array =
//code goes here
// other implementations
它加载正确,没有任何错误,并且它附带的所有程序集也正常加载。 当我从附加的扩展中获取所有处理器时,问题就出现了。 以下是描述模块及其如何提供处理器的代码的简化表示:
type EmguRecognitionModule() =
inherit RecognitionModule()
override this.GetRecognitionProcessor() : IRecognitionProcessor =
new EmguFaceRecognition() :> IRecognitionProcessor
// more code goes here
加载新模块时 - 它的处理器被提取并存储在存储器中。 通过Activator.CreateInstance实例化模块和通过GetRecognitionProcessor方法获取它的处理器这两个步骤都可以正常工作。 这是填充我的视图模型的处理器集合之一的方法:
public void PopulateRecognitionProcessors(IEnumerable<IRecognitionProcessor> processors, AccessToken accessToken)
{
if (accessToken != _parentAccessToken)
throw new AccessViolationException("Attempt to set recognition processors from outside of the parent");
_recognitionProcessors.Clear();
_recognitionProcessors.AddRange(processors);
SelectedProcessor = _recognitionProcessors.FirstOrDefault();
}
非常简单,尽管当处理器来自 F# 库时效果不佳。 即使有处理器, SelectedProcessor属性也根本不会分配给第一个处理器,它仍然是null 。 当我放置断点并尝试观察存储在集合中的处理器的属性时 - 检查显示没有任何属性。 这是我在 JetBrains Rider 中制作的属性检查示例的链接。 但是当我使用Evaluate窗口时,我可以访问对象的所有属性和方法,并且 IntelliSense 可以完美运行。 链接到带有评估示例的图像。 整个情况让我感到愚蠢。 只是第一次遇到这个问题。 以前,我使用 F# 库中定义的类型的所有尝试都成功了。 但这次是个例外。 我看到使用从抽象类型派生的类型效果很好。 但是以某种方式实现接口的类型却没有。
在使用 F# 项目设置并从头开始重新创建项目后,我终于设法解决了这个问题——尽管问题的根源仍然是个谜。
但是 Rider 的属性检查器仍然存在问题,它只显示直接在接口后代中声明的那些成员。 如果已经发布了类似的问题,我会查看 JetBrains 支持。
更新
似乎CheckBox的DisplayMemberPath (在XAML中指定)也无法从实例解析已实现的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.