Wolfgang Roth
Wolfgang Roth

Reputation: 483

Returning different types of function (out-) parameters

I am trying to write a method that takes a byte array as input and several other types as output variables. The method should be able to check the type of the "output" parameters and read the correct value from the byte array (this part works already).

But I cannot find an easy way to get the output parameters.

This is what I have so far (edited, because of missing comma):

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;
            }
        }
    }
}
}

While inside the Test method, the argsparameter has the correct values, but they naturally never get outside to their corresponding simple vars ui16, i16, and so on...

When I change the signature to

public static object[] Test(byte[] daten, object[] args);

And then return args; at the end of the function, I get my values outside of the function, but they are inside the object[], and I still would have to write something like this in 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];

passing args as reference parameter would work, but then I would have to declare another variable instead of passing new object[] { ui16, i16, ui32, i32, b }

I think, I would need a mixture of params and out:

public static void Test(byte[] daten, params out ui16, out i16, out ui32);

but params does not work with different types.

Upvotes: 0

Views: 154

Answers (1)

Adam Jachocki
Adam Jachocki

Reputation: 2124

Hmmm your problem is very simple or I don't understand it. The only thing you have to do is to declare your return object earlier and not to create it in function parameter. Just like that:

object[] result = new object[] { ui16, i16, ui32, i32, b };
Test(buffer, result);

Doing it your way:

Test(buffer, new object[] { ui16, i16, ui32, i32, b });

you just don't have any chance to get the result values, because this new object is destroyed as soon as Test method ends. But when you pass it as a reference to earlier created object, everything works as expected.

Upvotes: 1

Related Questions