【问题标题】:Something similar to UBound in C#类似于 C# 中的 UBound 的东西
【发布时间】:2014-03-23 22:17:28
【问题描述】:

在我努力学习 C# 的过程中,我用 Vb 和 C# 为一个小项目编写了代码。我已经取得了进展,但是在尝试实现在 Vb 中很容易实现的东西时遇到了问题。该例程从色谱系统中读取结果文件。当我尝试确定已处理峰的数组大小时,就会出现问题,这些峰的大小取决于各个峰的积分限制。我的目标是将它们填充到列表中,然后用于在 XY 图上显示峰值。我已经搜索过,通常提供两个选项,但它们对我不起作用,但也许还有其他一些我遗漏的东西。我尝试使用 GetUpperBounds 属性

nPoints = mySliceTable.get_RTsAt(j).GetUpperBound(0);

并引用 Microsoft.VisualBasic 并使用类似的东西

nPoints = Information.UBounds(mySliceTable.get_RTsAt(j);  

在任何一种情况下,我都会收到类似“无法将 'System.Double[*]' 类型的对象转换为 'System.Double[]' 类型的错误”。如果我尝试创建数组而不是确定其大小,这将是有意义的。

代码如下所示。我在粘贴整个班级时遇到问题。缺少的是命名空间、using 语句、类 def,然后是第一个显示对话框以获取要读取的文件名的方法。

任何建议将不胜感激。

谢谢,雷

    private void readFile(string file)
    {
        PLCirrusResults  myRstFile = new PLCirrusResults();

        myRstFile.Load(file);
        IPLCirrusRstSampleInfo mySampleInfo ;
        IPLCirrusRstSliceTable mySliceTable ;
        IPLCirrusRstProcessedPeaks myProcessedPeaks;

        mySampleInfo = (IPLCirrusRstSampleInfo)myRstFile;
        mySliceTable = (IPLCirrusRstSliceTable)myRstFile;
        myProcessedPeaks = (IPLCirrusRstProcessedPeaks)myRstFile;

        // read the sample info header
        string sampleName = mySampleInfo.SampleName.ToString();
        double conc = Convert.ToDouble(mySampleInfo.Concentration);
        double injVol = Convert.ToDouble(mySampleInfo.InjectionVolume);

        // read Slice Table
        int nPeaks = Convert.ToInt32(mySliceTable.NumberOfSliceTablePeaks);
        int nPoints = 0;

        IList<double> rTs = new List<double>();
        List<double> sConcs = new List<double>();
        List<double> normHts = new List<double>();
        List<double> responses = new List<double>();

        for (int j = 1; j <= nPeaks; j++) 
        {
            nPoints = mySliceTable.get_RTsAt(j).GetUpperBound(0);
            for (int i = 1; i <= nPoints; i++) 
            {
                rTs.Add(mySliceTable.get_RTsAt(j)(i));
                responses.Add(mySliceTable.get_ResponsesAt(j)(i));
                normHts.Add(mySliceTable.get_NormalisedHeightsAt(j)(i));
                sConcs.Add(mySliceTable.get_ConcentrationsAt(j)(i));
            }
        }
        string msg = String.Format("The sample is: {0}", sampleName);
        MessageBox.Show(msg, "file Info");
        }
    }

补充:抱歉耽搁了,说来话长。

堆栈跟踪:

[External Code] 
ElastGPCAnalysis.exe!GPC.Model.CirrusFiles.readFile(string file)` Line 71 -> this is the line with the GetUpperBounds(0);
ElasttGPCAnalysis.exe!GPC.Models.CirrusFiles.openFile()` Line 38
ElastGPC.exe!GPC.GPCViewModel.btnLoadSample()` Line 34

[External Code]

然后调用 Caliburn.micro。

回答有关如何定义 get_RTsAt 的问题。再次粘贴屏幕截图会更容易,但我还不能。所以我会写我能写的。

我引用的 dll 在众多可用接口之一中称为 PCLGRAMLib.dll 和 IPLCirrusRstSliceTable。 动态 get_RTsAt(int Peak) PLCGRAMLib.IPLCirrusRstSliceTable的成员来自对象浏览器。

【问题讨论】:

  • IPLCirrusRstSampleInfo.get_RTsAt() 是如何定义的?
  • .Length - 1 不够用的任何理由?
  • 请发布一段简单的代码来实际展示问题。扔掉不相关的代码,但包含足以重现问题的代码。例如,这缺少基本的 IPLCirrusRstSampleInfo.get_RTsAt() 定义。
  • 很难解释 GetUpperBound 是如何失败的。更多关于this question中的不合格数组@
  • @Ray_B123456 查看您的更新,在我看来,失败的行是myRstFile.Load(file);,与GetUpperBound(0); 无关。是什么让你如此相信?

标签: c#


【解决方案1】:

你能告诉我们get_RTsAt的声明吗?

C# 支持导出单维向量数组类型的元数据;但是,如果您有一个设计为非零的数组,您可能会遇到问题。

如果您是表示 get_RTsAt 的库的作者,请尝试将其结果类型设为 Array,而不是非零数组类型。

数组的向量化设计(根据定义,如果是单维数组,则保证为零索引,或 SD)存在通用中间语言操作码,可优化对此类数组的访问,从而激励使用零- 基于或向量的数组。

如果我的预感是正确的,那么您遇到的问题是 C# 正在尝试解析元数据,但它没有这样做。 C# 将从不导出非零单维数组的类型,并且在我编写编译器的测试中,我在尝试与 SD 非零数组互操作时遇到了问题。这方面的线索是您收到的错误,即:Unable to cast object of type 'System.Double[*]'to type 'System.Double[]' '*' 是您的提示,它会告诉您要注意什么。

编辑- 由于您无权访问原始来源,请尝试以下操作: 您能否尝试通过以下方式将 get_RTsAt 的结果转换为 Array:

var rts_at = (Array)(Object)mySliceTable.get_RTsAt(j);
nPoints = rts_at.GetUpperBounds(0);

告诉我这是否适合你。

【讨论】:

  • 不幸的是,我不是图书馆的作者,图书馆的历史可以追溯到 2000 年左右。我已询问供应商是否有新版本的 SDK,但尚未得到回复。但据我所知,在 Vb 代码中,数组不是从零开始的。
  • 我已经编辑了答案,让你尝试一些简单的事情,我必须编写 MSIL 来检查它,这样几分钟后就会到这里。
  • Drats,在我的一生中,我不记得几年前我是如何遇到这样的错误的。看起来好像您在 IL 中将类型明确声明为非向量数组并编译库,您会得到 C# 甚至无法与之互操作的东西。这让我想知道:您是否在与 COM 库进行交互?
  • 是的,我正在与 COM 库进行交互。但是您将 Object 转换为数组的建议确实有效。之后,我能够使用 GetUpperBounds 来获取数组的大小。但是我必须对所有数组执行相同的操作才能将数据放入列表中。有什么东西可以让使用 COM 库更容易吗?再次感谢您的帮助
  • 不是临时的,因为您正在与 COM 执行互操作,并且该 COM 库正在导出一些未在您提供的实际 COM 接口中表达的内容,所以您有点一个僵局。我可能有的唯一建议是对类型库进行逆向工程(RE)并手动修补它以使用 Array 类型,而不是他们提供的类型错误的 typestrict 版本的数组。尽管这可能会带来一些问题。您可以希望的最好的事情是您的供应商做出回应。不过,我很高兴将它转换为现在可以使用的数组。 -- 在 RE 上编辑:首先检查您的 EULA。
【解决方案2】:

在这种情况下,我个人会使用LengthCount。例如,我将在您的代码中使用以下内容:

for (int i = 1; i < mySliceTable.get_RTsAt(j).Length; i++)

请记住,在这种情况下,出于显而易见的原因,您需要将 &lt;= 更改为 &lt;

【讨论】:

  • 我忘了提到我曾尝试使用 .Length 却出现同样的错误。
  • @Ray_B123456 好吧,问题不在于您使用GetUpperBound()。哪一行给你错误?也许您可以发布堆栈跟踪。
  • 我会粘贴屏幕截图,但我没有足够的积分。那我就赶紧打出来
  • @Ray_B123456 只需编辑您的问题并将其粘贴到那里。
猜你喜欢
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
相关资源
最近更新 更多