Archived
This forum has been archived. Please start a new discussion on GitHub.
null sequence in C#
Hi,
I want to use sequence to send optional data. The idea is to pass null if a parameter is not needed
I made following tests using C#
module testOptional {
sequence<bool> boolSequence;
["clr:collection"] sequence<bool> boolCollectionSequence;
class DataClass {
boolCollectionSequence boolCollOpt;
boolSequence boolSeqOpt;
};
struct DataStruct {
boolCollectionSequence boolCollOpt;
boolSequence boolSeqOpt;
};
interface testOpt {
void fSeq(boolSequence value);
void fColl(boolCollectionSequence value);
void fClass(DataClass value);
void fStruct(DataStruct value);
};
};
1) On the client side I do fSeq(null), but the server receive an empty array bool[0] ?
Is this expected ? If yes, does it not mean to much overhead transmitting a empty array or transmitting a null array but instantiate a empty array on the server side
2) I have tried to use other techniques for transmitting null sequence each time I get an error on the client side
fColl(null)
System.NullReferenceException: Object reference not set to an instance of an object.
at testOptional.testOptDelM_.fColl(boolCollectionSequence value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 1198
at testOptional.testOptPrxHelper.fColl(boolCollectionSequence value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 908
at testOptional.testOptPrxHelper.fColl(boolCollectionSequence value) in C:\SydIceInterface\cs\testOptional.cs:line 896
at IceTimeClient.Class1.run(String[] args) in C:\IceTimeClient\Class1.cs:line 36
fClass(new DataClass())
System.NullReferenceException: Object reference not set to an instance of an object.
at testOptional.DataClass.write__(BasicStream os__) in C:\SydIceInterface\cs\testOptional.cs:line 471
at IceInternal.BasicStream.writeInstance(Object v, Int32 index)
at IceInternal.BasicStream.writePendingObjects()
at testOptional.testOptDelM_.fClass(DataClass value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 1157
at testOptional.testOptPrxHelper.fClass(DataClass value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 880
at testOptional.testOptPrxHelper.fClass(DataClass value) in C:\SydIceInterface\cs\testOptional.cs:line 868
at IceTimeClient.Class1.run(String[] args) in C:\IceTimeClient\Class1.cs:line 46
fStruct(new DataStruct())
System.NullReferenceException: Object reference not set to an instance of an object.
at testOptional.DataStruct.write__(BasicStream os__) in C:\SydIceInterface\cs\testOptional.cs:line 622
at testOptional.testOptDelM_.fStruct(DataStruct value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 1280
at testOptional.testOptPrxHelper.fStruct(DataStruct value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 964
at testOptional.testOptPrxHelper.fStruct(DataStruct value) in C:\SydIceInterface\cs\testOptional.cs:line 952
at IceTimeClient.Class1.run(String[] args) in C:\IceTimeClient\Class1.cs:line 55
Thank you for your help
I want to use sequence to send optional data. The idea is to pass null if a parameter is not needed
I made following tests using C#
module testOptional {
sequence<bool> boolSequence;
["clr:collection"] sequence<bool> boolCollectionSequence;
class DataClass {
boolCollectionSequence boolCollOpt;
boolSequence boolSeqOpt;
};
struct DataStruct {
boolCollectionSequence boolCollOpt;
boolSequence boolSeqOpt;
};
interface testOpt {
void fSeq(boolSequence value);
void fColl(boolCollectionSequence value);
void fClass(DataClass value);
void fStruct(DataStruct value);
};
};
1) On the client side I do fSeq(null), but the server receive an empty array bool[0] ?
Is this expected ? If yes, does it not mean to much overhead transmitting a empty array or transmitting a null array but instantiate a empty array on the server side
2) I have tried to use other techniques for transmitting null sequence each time I get an error on the client side
fColl(null)
System.NullReferenceException: Object reference not set to an instance of an object.
at testOptional.testOptDelM_.fColl(boolCollectionSequence value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 1198
at testOptional.testOptPrxHelper.fColl(boolCollectionSequence value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 908
at testOptional.testOptPrxHelper.fColl(boolCollectionSequence value) in C:\SydIceInterface\cs\testOptional.cs:line 896
at IceTimeClient.Class1.run(String[] args) in C:\IceTimeClient\Class1.cs:line 36
fClass(new DataClass())
System.NullReferenceException: Object reference not set to an instance of an object.
at testOptional.DataClass.write__(BasicStream os__) in C:\SydIceInterface\cs\testOptional.cs:line 471
at IceInternal.BasicStream.writeInstance(Object v, Int32 index)
at IceInternal.BasicStream.writePendingObjects()
at testOptional.testOptDelM_.fClass(DataClass value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 1157
at testOptional.testOptPrxHelper.fClass(DataClass value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 880
at testOptional.testOptPrxHelper.fClass(DataClass value) in C:\SydIceInterface\cs\testOptional.cs:line 868
at IceTimeClient.Class1.run(String[] args) in C:\IceTimeClient\Class1.cs:line 46
fStruct(new DataStruct())
System.NullReferenceException: Object reference not set to an instance of an object.
at testOptional.DataStruct.write__(BasicStream os__) in C:\SydIceInterface\cs\testOptional.cs:line 622
at testOptional.testOptDelM_.fStruct(DataStruct value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 1280
at testOptional.testOptPrxHelper.fStruct(DataStruct value, Context context__) in C:\SydIceInterface\cs\testOptional.cs:line 964
at testOptional.testOptPrxHelper.fStruct(DataStruct value) in C:\SydIceInterface\cs\testOptional.cs:line 952
at IceTimeClient.Class1.run(String[] args) in C:\IceTimeClient\Class1.cs:line 55
Thank you for your help
0
Comments
-
Hi Christian,
The Ice type system doesn't make any differences between a "null" sequence and an empty sequence. Being able to pass a null sequence in C# as a parameter of an Ice operation is just a convenience and is the same as passing an empty sequence. This is explained in the C# client side language mapping in the Ice manual, see the section "Null parameters" in section 14.12.2.
I don't think you should get these System.NullReferenceException though (the Ice runtime should consider the null reference as an empty sequence). I'll discuss this with our C# expert!
The best way to send an optional sequence is to encapsulate the sequence in a class (like your DataClass):sequence<bool> boolSequence; class OptionalSequence { boolSequence seq; }; interface testOpt { void opValue(OptionalSequence seq); };
To send a null sequence, you simply need to pass a null reference for the seq parameter: opValue(null).
Let us know if you need more information!
Cheers,
Benoit.0 -
Hi Benoit,
Thank you very much for your quick response. I was looking for my response in the slice language documentation instead of C# mapping doc.
In that case I have another question does the sending of an empty array implies a bigger message length than sending a null ?0 -
Hi,
No, an empty sequence (1 byte to encode the 0 size value) will actually be smaller to send than a null class pointer (4 bytes). This is documented in the Ice protocol chapter (Ch. 33) of the Ice manual.
Let us know if you need more information!
Cheers,
Benoit.0