在 Wolfram 中使用 LINQ

Using LINQ in Wolfram

我们有一个 C# 中的 IEnumerable 对象,我们想将其导入 Wolfram 金融平台。在当前的 C# API 中,我们使用 LINQ 查询从对象中 select 我们需要的特定对象。在 Wolfram Financial Platform 中,我们可以通过 NET/Link 导入 IEnumerable 对象(更多信息:http://reference.wolfram.com/language/NETLink/tutorial/Overview.html

导入对象后,即使导入了 LINQ 库,似乎也无法使用 LINQ 查询。此外,LINQ 查询中使用的 lambda 表达式在 Wolfram Financial Platform 中没有明确的替代品。他们有类似的东西叫做 "pure functions".

例子

C#

Object.Where(x => x.Property == Target).FirstOrDefault();

Wolfram

???[# == #.Property &, Object]`FirstOrDefault[];

当前尝试 + 错误

C#

client.GetMarketDataSnapshots(optionChain.Options.Select(x => x as Security).ToList());

Wolfram

client@GetMarketDataSnapshots[
   Map[CastNETObject[#, 
      "Core.Data.Securities.Security"] &, 
    optionChain@Options]];

错误

NET::netexcptn: "A .NET exception occurred: "System.ArgumentException: Object of type 'System.Collections.Generic.List`1[Core.Data.Securities.Option]' cannot be converted to type 'System.Collections.Generic.List`1[Core.Data.Securities.Security]'."

最终目标

使用 LINQ 查询或等价物从 C# API 中完整导入特定值到 Wolfram Financial Platform 中,以使用 Wolfram Financial Platform 语言编写程序(不允许以其他方式进行)随心所欲)。

错误消息说您正在尝试将 Core.Data.Securities.Option 的列表传递给 Core.Data.Securities.Security 的列表。因为 Core.Data.Securities.Option 没有 inherit/implement Core.Data.Securities.Security,你不能施放它。

您的代码:

client@GetMarketDataSnapshots[
Map[CastNETObject[#, 
    "Core.Data.Securities.Security"] &, 
optionChain@Options]];

应改为:

client@GetMarketDataSnapshots[
Map[CastNETObject[#, 
    "Core.Data.Securities.Option"] &, 
optionChain@Options]];

这会将 optionChain@Options 对象转换为 Core.Data.Securities.Option(这就是它的真实情况)。

评论后更新:

文档指出 "the vast majority of casts you see in .NET programs are irrelevant in .NET/Link." 除了 "working with COM objects" 和 "upcasts"。

假设您将 Core.Data.Securities.Option 的实例升级到 Core.Data.Securities.Security,只要所有 Option 实例都是真正的 Security 实例,您所做的就应该有效。

您的 C# 代码使用 as 关键字,它会尝试将变量转换为所需的类型,并在失败时返回 nullCastNETObject 没有说明这样做。在 C# 中,它等同于 client.GetMarketDataSnapshots(optionChain.Options.Select(x => (Security)x).ToList());.

你需要的是用 InstanceOf 检查数据类型并且只转换与 Security 兼容的对象。我认为它在 Wolfram 中看起来像这样(代码已更新以显示最终解决方案):

options = 
    NETNew["System.Collections.Generic.List`1[Core.Data.Securities.Security]"];

Scan[options@
    Add[CastNETObject[#, 
        "Core.Data.Securities.Security"]] &, 
    optionChain@Options@ToArray[]];

如果我写错了,这里是C#语法(所以你可以自己转换):

client.GetMarketDataSnapshots(optionChain.Options.Select(x => (x.GetType() == typeof(Security)) ? (Security)x : null).ToList());

性能更新(来自评论):

至于性能,可能没有更快的方法了。 Wolfram 专注于易用性和解决数学问题。它甚至与 .NET 接口这一事实令人惊讶。您的选择(如我所见)正在联系支持人员以查看是否有更快的系统或者他们可以解决问题,或者制作一个 .NET 方法来转换列表或包装函数以便只返回正确的类型。