返回不同类型的函数(out-)参数
Returning different types of function (out-) parameters
我正在尝试编写一种方法,将字节数组作为输入,将其他几种类型作为输出变量。该方法应该能够检查 "output" 参数的类型并从字节数组中读取正确的值(这部分已经工作)。
但是我找不到获取输出参数的简单方法。
这是我目前所拥有的(已编辑,因为缺少逗号):
using System;
using System.IO;
using System.Windows.Forms;
namespace TestSuite_flexComDotNet
{
static class Program
{
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
UInt16 ui16 = 0x0101;
Int16 i16 = 0x0202;
UInt32 ui32 = 0x03030303;
Int32 i32 = 0x04040404;
byte[] b = new byte[12];
for (int i = 0; i < b.Length; i++)
{
b[i] = (byte)(0x05 + i);
}
byte[] buffer;
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(ms);
bw.Write(ui16);
bw.Write(i16);
bw.Write(ui32);
bw.Write(i32);
bw.Write(b);
buffer = ms.GetBuffer();
Array.Resize(ref buffer, (int)ms.Position);
Test(buffer, new object[] { ui16, i16, ui32, i32, b });
ui16 = (UInt16) o[0];
i16 = (Int16) o[1];
ui32 = (UInt32) o[2];
i32 = (Int32) o[3];
b = (byte[])o[4];
}
public static Test(byte[] daten, object[] args)
{
MemoryStream ms = new MemoryStream(daten);
BinaryReader br = new BinaryReader(ms);
for (int i = 0; i < args.Length; i++)
{
switch (args[i])
{
case UInt16 _:
args[i] = br.ReadUInt16();
break;
case Int16 _:
args[i] = br.ReadInt16();
break;
case UInt32 _:
args[i] = br.ReadUInt32();
break;
case Int32 _:
args[i] = br.ReadInt32();
break;
case byte[] b:
{
args[i] = br.ReadBytes(b.Length);
}
break;
default:
break;
}
}
}
}
}
虽然在 Test
方法内部,args
参数具有正确的值,但它们自然不会超出其对应的简单变量 ui16
、i16
、等等...
当我把签名改成
public static object[] Test(byte[] daten, object[] args);
然后 return args;
在函数的末尾,我在函数外部得到我的值,但它们在 object[]
内部,我仍然必须在main
:
object[] o = Test(buffer, new object[] { ui16, i16, ui32, i32, b });
ui16 = (UInt16) o[0];
i16 = (Int16) o[1];
ui32 = (UInt32) o[2];
i32 = (Int32) o[3];
传递 args
作为参考参数是可行的,但是我必须声明另一个变量而不是传递 new object[] { ui16, i16, ui32, i32, b }
我想,我需要参数和输出的混合:
public static void Test(byte[] daten, params out ui16, out i16, out ui32);
但 params
不适用于不同的类型。
嗯嗯你的问题很简单或者我不明白。您唯一需要做的就是提前声明您的 return 对象,而不是在函数参数中创建它。就这样:
object[] result = new object[] { ui16, i16, ui32, i32, b };
Test(buffer, result);
按你的方式做:
Test(buffer, new object[] { ui16, i16, ui32, i32, b });
您只是没有任何机会获得结果值,因为一旦测试方法结束,这个新对象就会被销毁。
但是当您将它作为对先前创建的对象的引用传递时,一切都按预期工作。
我正在尝试编写一种方法,将字节数组作为输入,将其他几种类型作为输出变量。该方法应该能够检查 "output" 参数的类型并从字节数组中读取正确的值(这部分已经工作)。
但是我找不到获取输出参数的简单方法。
这是我目前所拥有的(已编辑,因为缺少逗号):
using System;
using System.IO;
using System.Windows.Forms;
namespace TestSuite_flexComDotNet
{
static class Program
{
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
UInt16 ui16 = 0x0101;
Int16 i16 = 0x0202;
UInt32 ui32 = 0x03030303;
Int32 i32 = 0x04040404;
byte[] b = new byte[12];
for (int i = 0; i < b.Length; i++)
{
b[i] = (byte)(0x05 + i);
}
byte[] buffer;
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(ms);
bw.Write(ui16);
bw.Write(i16);
bw.Write(ui32);
bw.Write(i32);
bw.Write(b);
buffer = ms.GetBuffer();
Array.Resize(ref buffer, (int)ms.Position);
Test(buffer, new object[] { ui16, i16, ui32, i32, b });
ui16 = (UInt16) o[0];
i16 = (Int16) o[1];
ui32 = (UInt32) o[2];
i32 = (Int32) o[3];
b = (byte[])o[4];
}
public static Test(byte[] daten, object[] args)
{
MemoryStream ms = new MemoryStream(daten);
BinaryReader br = new BinaryReader(ms);
for (int i = 0; i < args.Length; i++)
{
switch (args[i])
{
case UInt16 _:
args[i] = br.ReadUInt16();
break;
case Int16 _:
args[i] = br.ReadInt16();
break;
case UInt32 _:
args[i] = br.ReadUInt32();
break;
case Int32 _:
args[i] = br.ReadInt32();
break;
case byte[] b:
{
args[i] = br.ReadBytes(b.Length);
}
break;
default:
break;
}
}
}
}
}
虽然在 Test
方法内部,args
参数具有正确的值,但它们自然不会超出其对应的简单变量 ui16
、i16
、等等...
当我把签名改成
public static object[] Test(byte[] daten, object[] args);
然后 return args;
在函数的末尾,我在函数外部得到我的值,但它们在 object[]
内部,我仍然必须在main
:
object[] o = Test(buffer, new object[] { ui16, i16, ui32, i32, b });
ui16 = (UInt16) o[0];
i16 = (Int16) o[1];
ui32 = (UInt32) o[2];
i32 = (Int32) o[3];
传递 args
作为参考参数是可行的,但是我必须声明另一个变量而不是传递 new object[] { ui16, i16, ui32, i32, b }
我想,我需要参数和输出的混合:
public static void Test(byte[] daten, params out ui16, out i16, out ui32);
但 params
不适用于不同的类型。
嗯嗯你的问题很简单或者我不明白。您唯一需要做的就是提前声明您的 return 对象,而不是在函数参数中创建它。就这样:
object[] result = new object[] { ui16, i16, ui32, i32, b };
Test(buffer, result);
按你的方式做:
Test(buffer, new object[] { ui16, i16, ui32, i32, b });
您只是没有任何机会获得结果值,因为一旦测试方法结束,这个新对象就会被销毁。 但是当您将它作为对先前创建的对象的引用传递时,一切都按预期工作。