Generics and casting questions

L

LongBow

Hello all,

First of all, sorry for multiple question per one thread. I have two
questions. First what I think might be the easier problem. I am
capturing data from an embedded device which I need to display data.
One particular piece of data is a 32 bit floating point value. The
problem I am having is converting the 4-byte value which is read via
an RS-232 link. How can I cast the 4-byte value to a value type float
correctly? I have tried placing shifting the bytes into either a int
or UInt32 (which is a class from what I understand) then casting that
value as a float, but it doesn't work correctly. This operation looks
similar to


int value = (int)((byteCode[0] << 24 ) |
(byteCode[1] << 16 ) |
(byteCode[2] << 8 ) |
(byteCode[3] ));

float valueF = (float)value;

This obviosuly doesn't appear to work correctly. The embedded device
stores the 32-bit float in the standard IEEE format from my current
understanding which should be compatable with the MS compiler. So how
would I get this conversion to work correctly?


The second question I have deals with using Generics. I have an
interface which looks like


interface IScriptVar<T> where T : struct
{
string ToString();
string ToHexString( );
void SetValue( T value, UInt32 index );
void SetValue( T[] values, int index );
T GetValue( int index );
....
}

public class CScriptVar<T> : IScriptVar<T> where T : struct
{
... Implemented Interface methods and members
}

which I have also created a List for them

public class CScriptVarStringList<CScriptVarString> :
IList<CScriptVarString>
{
....
}

Then in my code I have the following

private CScriptVarList<CScriptVar<byte>> ScriptVarsBytes;
private CScriptVarList<CScriptVar<short>> ScriptVarsShort;
private CScriptVarList<CScriptVar<int>> ScriptVarsInts;
private CScriptVarList<CScriptVar<float>> ScriptVarsFloat;

I have a method when passed in certain arguments it will return on the
of the objects. Since they all implement several interfaces I would
like to return the object and then cast it to the generic/general type
of IScriptVar<T>, but this does not work correctly. I have something
like the following currently, but I don't think it is right since I am
forced to qualify using a (struct or data types) byte, short, int or
float.

((IScriptVar<int>)scriptVar).ToHexString();

or

((CScriptVar<int>)scriptVar).ToHexString();


I was hoping to use a generic form, but perhaps this is not possible.
When I retrieve the object I could perform a typeof conditional then
switch between each one of the System.Type (struct or data types)
which would look like

if ( scriptVar.GetType() == typeof(IScriptVar<byte>))
{ ((CScriptVar<byte>)scriptVar).ToHexString(); }

if ( scriptVar.GetType() == typeof(IScriptVar<short>))
{ ((CScriptVar<short>)scriptVar).ToHexString(); }

if ( scriptVar.GetType() == typeof(IScriptVar<int>))
{ ((CScriptVar<int>)scriptVar).ToHexString(); }

if ( scriptVar.GetType() == typeof(IScriptVar<float>))
{ ((CScriptVar<float>)scriptVar).ToHexString(); }

Does anyone know of a elegant way of handling this or perhaps a better
approach.

Mark
 
J

Joanna Carter [TeamB]

"LongBow" <[email protected]> a écrit dans le message de (e-mail address removed)...

| Does anyone know of a elegant way of handling this or perhaps a better
| approach.

I would separate out the non-generic methods of the interface to a
non-generic base interface and then derive the generic interface from that :

interface IScriptVar
{
string ToString();
string ToHexString( );
}

interface IScriptVar<T> : IScriptVar where T : struct
{
void SetValue( T value, UInt32 index );
void SetValue( T[] values, int index );
T GetValue( int index );
....
}

Then you can treat all instances the same as IScriptVar, allowing you to
access the ToString and ToHexString methods without having to know the exact
type.

Joanna
 
L

Larry Lard

LongBow said:
First what I think might be the easier problem. I am
capturing data from an embedded device which I need to display data.
One particular piece of data is a 32 bit floating point value. The
problem I am having is converting the 4-byte value which is read via
an RS-232 link. How can I cast the 4-byte value to a value type float
correctly? I have tried placing shifting the bytes into either a int
or UInt32 (which is a class from what I understand) then casting that
value as a float, but it doesn't work correctly. This operation looks
similar to


int value = (int)((byteCode[0] << 24 ) |
(byteCode[1] << 16 ) |
(byteCode[2] << 8 ) |
(byteCode[3] ));

float valueF = (float)value;

This is at too high a level - this looks at the *number* in the int and
just makes valueF have the same *numerical* value. You want to be
working at the bit level.
This obviosuly doesn't appear to work correctly. The embedded device
stores the 32-bit float in the standard IEEE format from my current
understanding which should be compatable with the MS compiler. So how
would I get this conversion to work correctly?

Use BitConverter.ToSingle on the byte array.
 
L

LordHog

Larry said:
LongBow said:
First what I think might be the easier problem. I am
capturing data from an embedded device which I need to display data.
One particular piece of data is a 32 bit floating point value. The
problem I am having is converting the 4-byte value which is read via
an RS-232 link. How can I cast the 4-byte value to a value type float
correctly? I have tried placing shifting the bytes into either a int
or UInt32 (which is a class from what I understand) then casting that
value as a float, but it doesn't work correctly. This operation looks
similar to


int value = (int)((byteCode[0] << 24 ) |
(byteCode[1] << 16 ) |
(byteCode[2] << 8 ) |
(byteCode[3] ));

float valueF = (float)value;

This is at too high a level - this looks at the *number* in the int and
just makes valueF have the same *numerical* value. You want to be
working at the bit level.
This obviosuly doesn't appear to work correctly. The embedded device
stores the 32-bit float in the standard IEEE format from my current
understanding which should be compatable with the MS compiler. So how
would I get this conversion to work correctly?

Use BitConverter.ToSingle on the byte array.

I had an additional question, why isn't type T allowed for the
BitConverter class? The Convert class allows type T to be used. Is
there a specific reason why? I have also noticed that bit wise
operations are not allowed for type T operation also. Why is the case?
I figure since the width of the data type is not known until run-time
so the bit wise operation doesn't know which opcode to use during
compile time.

Yes, thanks for both individuals who have replied as it has helped
greatly. I am still having problems the generics as bit-wise operations
are not allowed and I can't use the BitConverter class for some of the
operation I want.

Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top