473,398 Members | 2,368 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

How To Obtain Type for Generic Conversion

I want to do something like this:

obj = CType(value, Value.Type)

Well, not exactly, but I think that captures the essence. I realise it won't
work as I have written it, and it looks a bit like a nebulous statement, but
I am looking for a generic way to convert a variable of unknown type to its
actual type.

Perhaps a better example would be

Enum MyEnum As Byte
AnElement
AnotherElement
End Enum

Dim e As MyEnum
Dim obj as Object

e = AnotherElement

obj = CType(e, Byte)

The thing is, I don't know, until runtime what the underlying type is.

Any thoughts?

TIA

Charles
Nov 20 '05 #1
6 5154
Hi Charles,

Can you not do something with overloaded functions: That much types are not
there and maybe even less when you know what you use.

function charles(byval item as integer) as integer
end function

function charles(byval item as string) as string
end function

I did not try it, just something that came up and maybe it helps you.

Cor

Nov 20 '05 #2
Hi Cor

I think, from what you are suggesting, that the compiler would have to know
at compile time what the type was, so that it could use the correct
overloaded function. In fact, the type won't be known until runtime.

What I am actually doing, is using reflection to translate a structure into
a byte array. As I iterate through the structure - which I am passed at
runtime - each element may have a different type, and I wish to convert each
type into the correct number of bytes for its internal storage.

Charles
"Cor Ligthert" <no**********@planet.nl> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Charles,

Can you not do something with overloaded functions: That much types are not there and maybe even less when you know what you use.

function charles(byval item as integer) as integer
end function

function charles(byval item as string) as string
end function

I did not try it, just something that came up and maybe it helps you.

Cor

Nov 20 '05 #3
Charles,
Have you tried:

Dim e As MyEnum = MyEnum.AnotherElement
Dim obj as Object

Dim theType As Type = GetType(Byte)

obj = Convert.ChangeType(value, theType)

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I want to do something like this:

obj = CType(value, Value.Type)

Well, not exactly, but I think that captures the essence. I realise it won't work as I have written it, and it looks a bit like a nebulous statement, but I am looking for a generic way to convert a variable of unknown type to its actual type.

Perhaps a better example would be

Enum MyEnum As Byte
AnElement
AnotherElement
End Enum

Dim e As MyEnum
Dim obj as Object

e = AnotherElement

obj = CType(e, Byte)

The thing is, I don't know, until runtime what the underlying type is.

Any thoughts?

TIA

Charles

Nov 20 '05 #4
Hi Jay

Thanks. I have tried it now, but it seems to work only for byte types.
Anything larger throws an exception "Value was either too large or too small
for an unsigned byte".

The code I currently have is below:

<code>
Public Shared Function ToByteArray(ByVal MyStruct As Object) As Byte()

' Convert a structure into a byte array

Dim al As ArrayList

Dim Fields As FieldInfo()

Try
Fields = MyStruct.GetType.GetFields

al = New ArrayList

For Each fld As FieldInfo In Fields
If fld.FieldType.Equals(GetType(Byte)) Then
' Add byte to array list
al.Add(CByte(fld.GetValue(MyStruct)))

ElseIf fld.FieldType.Equals(GetType(Int16)) Then
' Add 16-bit value to array list
Dim i16 As Int16

i16 = CType(fld.GetValue(MyStruct), Int16)

' Little-endian
al.Add(CByte(i16 And &HFF))
al.Add(CByte((i16 And &HFF00) >> 8))

' Big-endian
'al.Add(CByte(i16 >> 8))
'al.Add(CByte(i16 And &HFF))

ElseIf fld.FieldType.Equals(GetType(SomeEnumeratedValue))
Then
' This is coded as a byte
al.Add(CByte(fld.GetValue(MyStruct)))

ElseIf fld.FieldType.Equals(GetType(SomethingElse)) Then
' This is coded as a byte
al.Add(CByte(fld.GetValue(MyStruct)))

Else
Throw New Exception("Cannot convert type " &
fld.FieldType.ToString)
End If
Next fld

Catch ex As Exception
Throw

End Try

Return DirectCast(al.ToArray(GetType(Byte)), Byte())

End Function
</code>

As you will see, there is the potential for a lot of If .. Then ... Elses. I
am looking for a generic way to convert to save all the typing and
duplication. Any thoughts?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OJ*************@TK2MSFTNGP11.phx.gbl...
Charles,
Have you tried:

Dim e As MyEnum = MyEnum.AnotherElement
Dim obj as Object

Dim theType As Type = GetType(Byte)

obj = Convert.ChangeType(value, theType)

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I want to do something like this:

obj = CType(value, Value.Type)

Well, not exactly, but I think that captures the essence. I realise it

won't
work as I have written it, and it looks a bit like a nebulous statement,

but
I am looking for a generic way to convert a variable of unknown type to

its
actual type.

Perhaps a better example would be

Enum MyEnum As Byte
AnElement
AnotherElement
End Enum

Dim e As MyEnum
Dim obj as Object

e = AnotherElement

obj = CType(e, Byte)

The thing is, I don't know, until runtime what the underlying type is.

Any thoughts?

TIA

Charles


Nov 20 '05 #5
Charles,
Thanks. I have tried it now, but it seems to work only for byte types.
Anything larger throws an exception "Value was either too large or too small for an unsigned byte".
The code I gave IS for byte types! Notice the GetType(Byte) in there, you
would need to change GetType(Byte) to the specific type you are interested
in (for example FieldInfo.FieldType). Remember an Enum can be Byte, Short,
Integer or Long.
Dim theType As Type = GetType(Byte) ' convert to byte Dim theType As Type = GetType(Integer) ' convert to integer
Dim theType As Type = GetType(String) ' convert to string
Dim theType As Type = GetType(Double) ' convert to double obj = Convert.ChangeType(value, theType)
Unfortunately it does not really make sense to convert an integer to an
integer, as I don't see that really buys you anything!

What are you really attempting to do???

Have you looked at BinarySerialization?
I would use a MemoryStream & BinaryWriter if I really needed to implement
the ToByteArray routine. Something like:

' Convert a structure into a byte array
Public Shared Function ToByteArray(ByVal MyStruct As Object) As Byte()
Dim stream As New MemoryStream
Dim writer As New BinaryWriter(stream)
Dim fields() As FieldInfo = MyStruct.GetType().GetFields()
For Each fld As FieldInfo In fields
If fld.FieldType Is GetType(Byte) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), Byte))
ElseIf fld.FieldType Is GetType(Short) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), Short))
ElseIf fld.FieldType Is GetType(Integer) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), Integer))
ElseIf fld.FieldType Is GetType(String) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), String))
ElseIf fld.FieldType.IsEnum Then
' find the underlying type of enum and write that.
Else
' get all the fields on the Structure or Class fields
writer.Write(ToByteArray(fld.GetValue(MyStruct)))
End If
Next fld

Return stream.GetBuffer()
End Function

Alternatively you can use BitConverter.GetBytes to get an array of bytes
given a value.

Note both BinaryWriter & GetBytes don't allow you to work with an object
variable directly.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:OZ**************@TK2MSFTNGP11.phx.gbl... Hi Jay

Thanks. I have tried it now, but it seems to work only for byte types.
Anything larger throws an exception "Value was either too large or too small for an unsigned byte".

The code I currently have is below:

<code>
Public Shared Function ToByteArray(ByVal MyStruct As Object) As Byte()

' Convert a structure into a byte array

Dim al As ArrayList

Dim Fields As FieldInfo()

Try
Fields = MyStruct.GetType.GetFields

al = New ArrayList

For Each fld As FieldInfo In Fields
If fld.FieldType.Equals(GetType(Byte)) Then
' Add byte to array list
al.Add(CByte(fld.GetValue(MyStruct)))

ElseIf fld.FieldType.Equals(GetType(Int16)) Then
' Add 16-bit value to array list
Dim i16 As Int16

i16 = CType(fld.GetValue(MyStruct), Int16)

' Little-endian
al.Add(CByte(i16 And &HFF))
al.Add(CByte((i16 And &HFF00) >> 8))

' Big-endian
'al.Add(CByte(i16 >> 8))
'al.Add(CByte(i16 And &HFF))

ElseIf fld.FieldType.Equals(GetType(SomeEnumeratedValue))
Then
' This is coded as a byte
al.Add(CByte(fld.GetValue(MyStruct)))

ElseIf fld.FieldType.Equals(GetType(SomethingElse)) Then
' This is coded as a byte
al.Add(CByte(fld.GetValue(MyStruct)))

Else
Throw New Exception("Cannot convert type " &
fld.FieldType.ToString)
End If
Next fld

Catch ex As Exception
Throw

End Try

Return DirectCast(al.ToArray(GetType(Byte)), Byte())

End Function
</code>

As you will see, there is the potential for a lot of If .. Then ... Elses. I am looking for a generic way to convert to save all the typing and
duplication. Any thoughts?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:OJ*************@TK2MSFTNGP11.phx.gbl...
Charles,
Have you tried:

Dim e As MyEnum = MyEnum.AnotherElement
Dim obj as Object

Dim theType As Type = GetType(Byte)

obj = Convert.ChangeType(value, theType)

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I want to do something like this:

obj = CType(value, Value.Type)

Well, not exactly, but I think that captures the essence. I realise it

won't
work as I have written it, and it looks a bit like a nebulous

statement, but
I am looking for a generic way to convert a variable of unknown type
to its
actual type.

Perhaps a better example would be

Enum MyEnum As Byte
AnElement
AnotherElement
End Enum

Dim e As MyEnum
Dim obj as Object

e = AnotherElement

obj = CType(e, Byte)

The thing is, I don't know, until runtime what the underlying type is.

Any thoughts?

TIA

Charles



Nov 20 '05 #6
Hi Jay

I have several structures that represent message packets. I want to be able
to take any one of these structures and convert it into a byte array so I
can send it down the line. Thus, I would have a single routine that could
take any of these structures and send it.

I don't want to have a series of If.... Thens because the structure could
contain a more complex type. I am only interested in the byte-by-byte
representation of the data in the structure. It is perhaps complicated by
the fact that multi-byte types need to be sent little-endian.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uB**************@TK2MSFTNGP12.phx.gbl...
Charles,
Thanks. I have tried it now, but it seems to work only for byte types.
Anything larger throws an exception "Value was either too large or too small
for an unsigned byte".


The code I gave IS for byte types! Notice the GetType(Byte) in there, you
would need to change GetType(Byte) to the specific type you are interested
in (for example FieldInfo.FieldType). Remember an Enum can be Byte, Short,
Integer or Long.
Dim theType As Type = GetType(Byte) ' convert to byte Dim theType As Type = GetType(Integer) ' convert to integer
Dim theType As Type = GetType(String) ' convert to string
Dim theType As Type = GetType(Double) ' convert to double obj = Convert.ChangeType(value, theType)
Unfortunately it does not really make sense to convert an integer to an
integer, as I don't see that really buys you anything!

What are you really attempting to do???

Have you looked at BinarySerialization?
I would use a MemoryStream & BinaryWriter if I really needed to implement
the ToByteArray routine. Something like:

' Convert a structure into a byte array
Public Shared Function ToByteArray(ByVal MyStruct As Object) As Byte()
Dim stream As New MemoryStream
Dim writer As New BinaryWriter(stream)
Dim fields() As FieldInfo = MyStruct.GetType().GetFields()
For Each fld As FieldInfo In fields
If fld.FieldType Is GetType(Byte) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), Byte))
ElseIf fld.FieldType Is GetType(Short) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), Short))
ElseIf fld.FieldType Is GetType(Integer) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), Integer))
ElseIf fld.FieldType Is GetType(String) Then
writer.Write(DirectCast(fld.GetValue(MyStruct), String))
ElseIf fld.FieldType.IsEnum Then
' find the underlying type of enum and write that.
Else
' get all the fields on the Structure or Class fields
writer.Write(ToByteArray(fld.GetValue(MyStruct)))
End If
Next fld

Return stream.GetBuffer()
End Function

Alternatively you can use BitConverter.GetBytes to get an array of bytes
given a value.

Note both BinaryWriter & GetBytes don't allow you to work with an object
variable directly.

Hope this helps
Jay
"Charles Law" <bl***@nowhere.com> wrote in message
news:OZ**************@TK2MSFTNGP11.phx.gbl...
Hi Jay

Thanks. I have tried it now, but it seems to work only for byte types.
Anything larger throws an exception "Value was either too large or too

small
for an unsigned byte".

The code I currently have is below:

<code>
Public Shared Function ToByteArray(ByVal MyStruct As Object) As Byte()
' Convert a structure into a byte array

Dim al As ArrayList

Dim Fields As FieldInfo()

Try
Fields = MyStruct.GetType.GetFields

al = New ArrayList

For Each fld As FieldInfo In Fields
If fld.FieldType.Equals(GetType(Byte)) Then
' Add byte to array list
al.Add(CByte(fld.GetValue(MyStruct)))

ElseIf fld.FieldType.Equals(GetType(Int16)) Then
' Add 16-bit value to array list
Dim i16 As Int16

i16 = CType(fld.GetValue(MyStruct), Int16)

' Little-endian
al.Add(CByte(i16 And &HFF))
al.Add(CByte((i16 And &HFF00) >> 8))

' Big-endian
'al.Add(CByte(i16 >> 8))
'al.Add(CByte(i16 And &HFF))

ElseIf fld.FieldType.Equals(GetType(SomeEnumeratedValue)) Then
' This is coded as a byte
al.Add(CByte(fld.GetValue(MyStruct)))

ElseIf fld.FieldType.Equals(GetType(SomethingElse)) Then
' This is coded as a byte
al.Add(CByte(fld.GetValue(MyStruct)))

Else
Throw New Exception("Cannot convert type " &
fld.FieldType.ToString)
End If
Next fld

Catch ex As Exception
Throw

End Try

Return DirectCast(al.ToArray(GetType(Byte)), Byte())

End Function
</code>

As you will see, there is the potential for a lot of If .. Then ... Elses. I
am looking for a generic way to convert to save all the typing and
duplication. Any thoughts?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message news:OJ*************@TK2MSFTNGP11.phx.gbl...
Charles,
Have you tried:

Dim e As MyEnum = MyEnum.AnotherElement
Dim obj as Object

Dim theType As Type = GetType(Byte)

obj = Convert.ChangeType(value, theType)

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
> I want to do something like this:
>
> obj = CType(value, Value.Type)
>
> Well, not exactly, but I think that captures the essence. I realise it won't
> work as I have written it, and it looks a bit like a nebulous

statement, but
> I am looking for a generic way to convert a variable of unknown type to its
> actual type.
>
> Perhaps a better example would be
>
> Enum MyEnum As Byte
> AnElement
> AnotherElement
> End Enum
>
> Dim e As MyEnum
> Dim obj as Object
>
> e = AnotherElement
>
> obj = CType(e, Byte)
>
> The thing is, I don't know, until runtime what the underlying type is. >
> Any thoughts?
>
> TIA
>
> Charles
>
>



Nov 20 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: tweak | last post by:
I'm struggling with the concept of typecasting when setting up a TCP client. Here's a code snip (modified from W. Richard Stevens Unix Programming book) to demonstrate where I am struggling: ...
4
by: Ken Varn | last post by:
I have an unknown numeric Type object passed into a function. I want to run a conversion on a string to convert the string to that Type object and return an object of that type. Is there some way...
11
by: Demorsy | last post by:
I want to convert a string (or object) to a primitive type. But I don't know the type to convert to at run time. For example l have variable (lets say its an int): int unknownType = 0; And a...
3
by: pgconnolly | last post by:
/* foreach does implicit type conversion on elements of a params argument or Generic.List. * This is not good. * Examples of evil follow... */ using System; // I love it when C# is strict...
1
by: Jinsong Liu | last post by:
Hello Group: I am playing with .NET 2.0 Generic. I have a CarsList<T> Generic class, Is it possible that I can control what T could be? I want to ensure the T can only be classes derived from a...
4
by: Harold Howe | last post by:
I am running into a situation where the compiler complains that it cannot infer the type parameters of a generic method when one of the function arguments is an anonymous method. Here is a...
669
by: Xah Lee | last post by:
in March, i posted a essay “What is Expressiveness in a Computer Language”, archived at: http://xahlee.org/perl-python/what_is_expresiveness.html I was informed then that there is a academic...
9
by: Steve Richter | last post by:
in a generic class, can I code the class so that I can call a static method of the generic class T? In the ConvertFrom method of the generic TypeConvert class I want to write, I have a call to...
8
by: ThunderMusic | last post by:
Hi, We need to serialize (binary) objects containing generic collections. The thing is, when we try to get the objects back (deserialize) with a different instance of the application, we receive...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.