By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,743 Members | 1,072 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,743 IT Pros & Developers. It's quick & easy.

Using Type Class

P: n/a
I have a class named "myclass" and an arraylist containing elements of type
"MyClass". I want to get the value of a property of "MyClass" (a string
type) for one of the arraylist elements.

I can get this using:
dim b as string
b = DirectCast(myarraylist(0),myclass).myproperty

However, I want to use an object to define the type "MyClass" like:
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty

but I get a "c" type not defined. How can I do this?

Thanks for any help.
--
Dennis in Houston
Nov 21 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a
"Dennis" <De****@discussions.microsoft.com> schrieb:
I have a class named "myclass" and an arraylist
containing elements of type "MyClass".
Notice that 'MyClass' is a keyword in the VB.NET programming language.
I want to get the value of a property of "MyClass" (a string
type) for one of the arraylist elements.

I can get this using:
dim b as string
b = DirectCast(myarraylist(0),myclass).myproperty

However, I want to use an object to define the type "MyClass" like:
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty


\\\
If TypeOf myarraylist(0) Is Foo Then
b = DirectCast(myarraylist(0), Foo).MyProperty
ElseIf...Then
...
....
End If
///

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>
Nov 21 '05 #2

P: n/a
Dennis,

I cannot offer you much, however this will work
\\\
Public Class Example
Public Shared Sub Main()
Dim myarraylist As New ArrayList
Dim mywhatever As New WindowsApplication1.myclass
myarraylist.Add(mywhatever)
Dim b As String = DirectCast(myarraylist(0), _
WindowsApplication1.myclass).myproperty
If TypeOf myarraylist(0) Is WindowsApplication1.myclass Then
MessageBox.Show(DirectCast(myarraylist(0), _
WindowsApplication1.myclass).myproperty)
End If
End Sub
End Class
Public Class [myclass]
Public myproperty As String
Public Sub New()
myproperty = "Hello World"
End Sub
End Class
///

I would not use that myclass because it is very confusing because it is a
keyword in VBNet.
(And I used an very easy way for a property only to keep it short)

I hope this helps anyway a little bit?

Cor

"Dennis" <De****@discussions.microsoft.com>
..
I have a class named "myclass" and an arraylist containing elements of type
"MyClass". I want to get the value of a property of "MyClass" (a string
type) for one of the arraylist elements.

I can get this using:
dim b as string
b = DirectCast(myarraylist(0),myclass).myproperty

However, I want to use an object to define the type "MyClass" like:
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty

but I get a "c" type not defined. How can I do this?

Thanks for any help.
--
Dennis in Houston

Nov 21 '05 #3

P: n/a
Dennis,
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty
You cannot cast based on a Type variable, the DirectCast needs the name
(myclass) of the type at compile time.

If you truly want to get AnyProperty form an ArrayList of AnyClass, the
"easist" way is to use CallByName

Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
Alternatively I will use a PropertyDescriptor or Reflection.

Something like:

Dim properties As System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (list(0))

Dim o As Object = properties("MyProperty").GetValue(list(0))

However I normally only use PropertyDescriptor in more advanced cases...

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:1F**********************************@microsof t.com...I have a class named "myclass" and an arraylist containing elements of type
"MyClass". I want to get the value of a property of "MyClass" (a string
type) for one of the arraylist elements.

I can get this using:
dim b as string
b = DirectCast(myarraylist(0),myclass).myproperty

However, I want to use an object to define the type "MyClass" like:
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty

but I get a "c" type not defined. How can I do this?

Thanks for any help.
--
Dennis in Houston

Nov 21 '05 #4

P: n/a
Thanks Jay and Cor. I was thinking about the CallbyName but I didn't know it
would work with a general arraylist of classes. Following is what I ended up
with that will sort any arraylist of classes (must be same class types) by
any string or integer or decimal property of the class in ascending or
descending order:

dim myArrayList as ArrayList
'Set each element of the ArrayList to any class (must all be of same type)
Dim mycomparer As New mycompare

mycomparer.propertyname = col
mycomparer.ascending = True
myArrayList.Sort(mycomparer)
.......
.......
__________________________________________________ ________________
Protected Class mycompare
Implements IComparer
Public propertyname As String
Public ascending As Boolean
Private Function Compare(ByVal x As Object, ByVal y As Object) As Integer
_ Implements IComparer.Compare
If ascending Then
Return New CaseInsensitiveComparer().Compare(CallByName(x, _
propertyname, CallType.Get), CallByName(y, propertyname, _ CallType.Get))
Else
Return New CaseInsensitiveComparer().Compare(CallByName(y, _
propertyname, CallType.Get), CallByName(x, propertyname, _ CallType.Get))
End If
End Function
End Class
__________________________________________________ _____________

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty


You cannot cast based on a Type variable, the DirectCast needs the name
(myclass) of the type at compile time.

If you truly want to get AnyProperty form an ArrayList of AnyClass, the
"easist" way is to use CallByName

Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
Alternatively I will use a PropertyDescriptor or Reflection.

Something like:

Dim properties As System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (list(0))

Dim o As Object = properties("MyProperty").GetValue(list(0))

However I normally only use PropertyDescriptor in more advanced cases...

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:1F**********************************@microsof t.com...
I have a class named "myclass" and an arraylist containing elements of type
"MyClass". I want to get the value of a property of "MyClass" (a string
type) for one of the arraylist elements.

I can get this using:
dim b as string
b = DirectCast(myarraylist(0),myclass).myproperty

However, I want to use an object to define the type "MyClass" like:
dim C as type = type.GetType(myarraylist(0))
b = DirectCast(myarraylist(0), C ).MyProperty

but I get a "c" type not defined. How can I do this?

Thanks for any help.
--
Dennis in Houston


Nov 21 '05 #5

P: n/a
Dennis,
Actually your code will work on two objects of different types as long as
they have the same property names.

For example, your class will compare the these two classes without any
problems:

Public Class Class1

Public ReadOnly Property Test() As String
...

End Class

Public Class Class2

Public ReadOnly Property Test() As String
...

End Class

Jay
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:E1**********************************@microsof t.com...
Thanks Jay and Cor. I was thinking about the CallbyName but I didn't know
it
would work with a general arraylist of classes. Following is what I ended
up
with that will sort any arraylist of classes (must be same class types) by
any string or integer or decimal property of the class in ascending or
descending order:

dim myArrayList as ArrayList
'Set each element of the ArrayList to any class (must all be of same type)
Dim mycomparer As New mycompare

mycomparer.propertyname = col
mycomparer.ascending = True
myArrayList.Sort(mycomparer)
.......
.......
__________________________________________________ ________________
Protected Class mycompare
Implements IComparer
Public propertyname As String
Public ascending As Boolean
Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer
_ Implements IComparer.Compare
If ascending Then
Return New CaseInsensitiveComparer().Compare(CallByName(x, _
propertyname, CallType.Get), CallByName(y, propertyname, _ CallType.Get))
Else
Return New CaseInsensitiveComparer().Compare(CallByName(y, _
propertyname, CallType.Get), CallByName(x, propertyname, _ CallType.Get))
End If
End Function
End Class
__________________________________________________ _____________

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
> dim C as type = type.GetType(myarraylist(0))
> b = DirectCast(myarraylist(0), C ).MyProperty


You cannot cast based on a Type variable, the DirectCast needs the name
(myclass) of the type at compile time.

If you truly want to get AnyProperty form an ArrayList of AnyClass, the
"easist" way is to use CallByName

Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
Alternatively I will use a PropertyDescriptor or Reflection.

Something like:

Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (list(0))

Dim o As Object = properties("MyProperty").GetValue(list(0))

However I normally only use PropertyDescriptor in more advanced cases...

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:1F**********************************@microsof t.com...
>I have a class named "myclass" and an arraylist containing elements of
>type
> "MyClass". I want to get the value of a property of "MyClass" (a
> string
> type) for one of the arraylist elements.
>
> I can get this using:
> dim b as string
> b = DirectCast(myarraylist(0),myclass).myproperty
>
> However, I want to use an object to define the type "MyClass" like:
> dim C as type = type.GetType(myarraylist(0))
> b = DirectCast(myarraylist(0), C ).MyProperty
>
> but I get a "c" type not defined. How can I do this?
>
> Thanks for any help.
>
>
> --
> Dennis in Houston


Nov 21 '05 #6

P: n/a
You are, of course as usual, correct. I was just trying to simpify my
explaination. The major drawback, I think, is speed. I probably would be
faster to use the object with properties directly and use late binding rather
than CallbyName. But anyway, it's pretty fast for small arraylists, arrays,
etc. Thanks again for your help.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
Actually your code will work on two objects of different types as long as
they have the same property names.

For example, your class will compare the these two classes without any
problems:

Public Class Class1

Public ReadOnly Property Test() As String
...

End Class

Public Class Class2

Public ReadOnly Property Test() As String
...

End Class

Jay
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:E1**********************************@microsof t.com...
Thanks Jay and Cor. I was thinking about the CallbyName but I didn't know
it
would work with a general arraylist of classes. Following is what I ended
up
with that will sort any arraylist of classes (must be same class types) by
any string or integer or decimal property of the class in ascending or
descending order:

dim myArrayList as ArrayList
'Set each element of the ArrayList to any class (must all be of same type)
Dim mycomparer As New mycompare

mycomparer.propertyname = col
mycomparer.ascending = True
myArrayList.Sort(mycomparer)
.......
.......
__________________________________________________ ________________
Protected Class mycompare
Implements IComparer
Public propertyname As String
Public ascending As Boolean
Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer
_ Implements IComparer.Compare
If ascending Then
Return New CaseInsensitiveComparer().Compare(CallByName(x, _
propertyname, CallType.Get), CallByName(y, propertyname, _ CallType.Get))
Else
Return New CaseInsensitiveComparer().Compare(CallByName(y, _
propertyname, CallType.Get), CallByName(x, propertyname, _ CallType.Get))
End If
End Function
End Class
__________________________________________________ _____________

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
> dim C as type = type.GetType(myarraylist(0))
> b = DirectCast(myarraylist(0), C ).MyProperty

You cannot cast based on a Type variable, the DirectCast needs the name
(myclass) of the type at compile time.

If you truly want to get AnyProperty form an ArrayList of AnyClass, the
"easist" way is to use CallByName

Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
Alternatively I will use a PropertyDescriptor or Reflection.

Something like:

Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (list(0))

Dim o As Object = properties("MyProperty").GetValue(list(0))

However I normally only use PropertyDescriptor in more advanced cases...

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:1F**********************************@microsof t.com...
>I have a class named "myclass" and an arraylist containing elements of
>type
> "MyClass". I want to get the value of a property of "MyClass" (a
> string
> type) for one of the arraylist elements.
>
> I can get this using:
> dim b as string
> b = DirectCast(myarraylist(0),myclass).myproperty
>
> However, I want to use an object to define the type "MyClass" like:
> dim C as type = type.GetType(myarraylist(0))
> b = DirectCast(myarraylist(0), C ).MyProperty
>
> but I get a "c" type not defined. How can I do this?
>
> Thanks for any help.
>
>
> --
> Dennis in Houston


Nov 21 '05 #7

P: n/a
Dennis,
The major drawback, I think, is speed. Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class
>> > dim C as type = type.GetType(myarraylist(0)) Dim mycomparer as new mycombare(C, col, True) > myArrayList.Sort(mycomparer)


Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com... You are, of course as usual, correct. I was just trying to simpify my
explaination. The major drawback, I think, is speed. I probably would be
faster to use the object with properties directly and use late binding
rather
than CallbyName. But anyway, it's pretty fast for small arraylists,
arrays,
etc. Thanks again for your help.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
Actually your code will work on two objects of different types as long as
they have the same property names.

For example, your class will compare the these two classes without any
problems:

Public Class Class1

Public ReadOnly Property Test() As String
...

End Class

Public Class Class2

Public ReadOnly Property Test() As String
...

End Class

Jay
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:E1**********************************@microsof t.com...
> Thanks Jay and Cor. I was thinking about the CallbyName but I didn't
> know
> it
> would work with a general arraylist of classes. Following is what I
> ended
> up
> with that will sort any arraylist of classes (must be same class types)
> by
> any string or integer or decimal property of the class in ascending or
> descending order:
>
> dim myArrayList as ArrayList
> 'Set each element of the ArrayList to any class (must all be of same
> type)
> Dim mycomparer As New mycompare
>
> mycomparer.propertyname = col
> mycomparer.ascending = True
> myArrayList.Sort(mycomparer)
> .......
> .......
> __________________________________________________ ________________
> Protected Class mycompare
> Implements IComparer
> Public propertyname As String
> Public ascending As Boolean
> Private Function Compare(ByVal x As Object, ByVal y As Object) As
> Integer
> _ Implements IComparer.Compare
> If ascending Then
> Return New CaseInsensitiveComparer().Compare(CallByName(x, _
> propertyname, CallType.Get), CallByName(y, propertyname, _
> CallType.Get))
> Else
> Return New CaseInsensitiveComparer().Compare(CallByName(y, _
> propertyname, CallType.Get), CallByName(x, propertyname, _
> CallType.Get))
> End If
> End Function
> End Class
> __________________________________________________ _____________
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> > dim C as type = type.GetType(myarraylist(0))
>> > b = DirectCast(myarraylist(0), C ).MyProperty
>>
>> You cannot cast based on a Type variable, the DirectCast needs the
>> name
>> (myclass) of the type at compile time.
>>
>> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> the
>> "easist" way is to use CallByName
>>
>> Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
>>
>>
>> Alternatively I will use a PropertyDescriptor or Reflection.
>>
>> Something like:
>>
>> Dim properties As
>> System.ComponentModel.PropertyDescriptorCollection
>> properties =
>> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>>
>> Dim o As Object = properties("MyProperty").GetValue(list(0))
>>
>> However I normally only use PropertyDescriptor in more advanced
>> cases...
>>
>> Hope this helps
>> Jay
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:1F**********************************@microsof t.com...
>> >I have a class named "myclass" and an arraylist containing elements
>> >of
>> >type
>> > "MyClass". I want to get the value of a property of "MyClass" (a
>> > string
>> > type) for one of the arraylist elements.
>> >
>> > I can get this using:
>> > dim b as string
>> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >
>> > However, I want to use an object to define the type "MyClass" like:
>> > dim C as type = type.GetType(myarraylist(0))
>> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >
>> > but I get a "c" type not defined. How can I do this?
>> >
>> > Thanks for any help.
>> >
>> >
>> > --
>> > Dennis in Houston
>>
>>
>>


Nov 21 '05 #8

P: n/a
Dennis,

I hope you saw that my example was early binding.

It depends how many classes you use however in my idea can it be an easy
approach.

I can me not immaging a situation where you do not know what kind of objects
you add to your arraylist so it should be as well be possible to collect
them in that way of my sample back.

(And than of course in a If ElseIf piece of code)

I hope this helps?

Cor
Nov 21 '05 #9

P: n/a
I am working on an application for my personal use that uses several
arraylists each of which has differing classes (some of which I haven't even
designed yet) and I want to use a class that inherits a DataGrid which sorts
on the click of a button by different properties (columns) in different
arraylists.

I can then click on the datagrid's column header and sort the arrarylists no
matter which arraylist to which the DataGrid is bound. It works great with
the CallByName but I read where this can be slow in a loop, of which, sorting
is a loop(s).

"Cor Ligthert" wrote:
Dennis,

I hope you saw that my example was early binding.

It depends how many classes you use however in my idea can it be an easy
approach.

I can me not immaging a situation where you do not know what kind of objects
you add to your arraylist so it should be as well be possible to collect
them in that way of my sample back.

(And than of course in a If ElseIf piece of code)

I hope this helps?

Cor

Nov 21 '05 #10

P: n/a
Thanks a lot. I'll try the two different methods (callbyname and
Propertydescriptor) and see how much faster the PropertyDescriptor is. Just
curious as to why you made the m_Ascending a ReadOnly since it's private
anyway and can't be accessed outside the class.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
The major drawback, I think, is speed.

Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class
>> > dim C as type = type.GetType(myarraylist(0)) Dim mycomparer as new mycombare(C, col, True) > myArrayList.Sort(mycomparer)


Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
You are, of course as usual, correct. I was just trying to simpify my
explaination. The major drawback, I think, is speed. I probably would be
faster to use the object with properties directly and use late binding
rather
than CallbyName. But anyway, it's pretty fast for small arraylists,
arrays,
etc. Thanks again for your help.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
Actually your code will work on two objects of different types as long as
they have the same property names.

For example, your class will compare the these two classes without any
problems:

Public Class Class1

Public ReadOnly Property Test() As String
...

End Class

Public Class Class2

Public ReadOnly Property Test() As String
...

End Class

Jay
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:E1**********************************@microsof t.com...
> Thanks Jay and Cor. I was thinking about the CallbyName but I didn't
> know
> it
> would work with a general arraylist of classes. Following is what I
> ended
> up
> with that will sort any arraylist of classes (must be same class types)
> by
> any string or integer or decimal property of the class in ascending or
> descending order:
>
> dim myArrayList as ArrayList
> 'Set each element of the ArrayList to any class (must all be of same
> type)
> Dim mycomparer As New mycompare
>
> mycomparer.propertyname = col
> mycomparer.ascending = True
> myArrayList.Sort(mycomparer)
> .......
> .......
> __________________________________________________ ________________
> Protected Class mycompare
> Implements IComparer
> Public propertyname As String
> Public ascending As Boolean
> Private Function Compare(ByVal x As Object, ByVal y As Object) As
> Integer
> _ Implements IComparer.Compare
> If ascending Then
> Return New CaseInsensitiveComparer().Compare(CallByName(x, _
> propertyname, CallType.Get), CallByName(y, propertyname, _
> CallType.Get))
> Else
> Return New CaseInsensitiveComparer().Compare(CallByName(y, _
> propertyname, CallType.Get), CallByName(x, propertyname, _
> CallType.Get))
> End If
> End Function
> End Class
> __________________________________________________ _____________
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> > dim C as type = type.GetType(myarraylist(0))
>> > b = DirectCast(myarraylist(0), C ).MyProperty
>>
>> You cannot cast based on a Type variable, the DirectCast needs the
>> name
>> (myclass) of the type at compile time.
>>
>> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> the
>> "easist" way is to use CallByName
>>
>> Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
>>
>>
>> Alternatively I will use a PropertyDescriptor or Reflection.
>>
>> Something like:
>>
>> Dim properties As
>> System.ComponentModel.PropertyDescriptorCollection
>> properties =
>> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>>
>> Dim o As Object = properties("MyProperty").GetValue(list(0))
>>
>> However I normally only use PropertyDescriptor in more advanced
>> cases...
>>
>> Hope this helps
>> Jay
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:1F**********************************@microsof t.com...
>> >I have a class named "myclass" and an arraylist containing elements
>> >of
>> >type
>> > "MyClass". I want to get the value of a property of "MyClass" (a
>> > string
>> > type) for one of the arraylist elements.
>> >
>> > I can get this using:
>> > dim b as string
>> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >
>> > However, I want to use an object to define the type "MyClass" like:
>> > dim C as type = type.GetType(myarraylist(0))
>> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >
>> > but I get a "c" type not defined. How can I do this?
>> >
>> > Thanks for any help.
>> >
>> >
>> > --
>> > Dennis in Houston
>>
>>
>>


Nov 21 '05 #11

P: n/a
Dennis,
I make member fields Read-only when the value of the field is not suppose to
change outside the Constructor (sub new) it keeps me honest when I am
writing the class, plus it keeps myself & subsequent programmers honest who
may modify the class later. Hopefully if they attempt to modify the field
and see it Read-only, then they will think a minute & research why its
read-only...

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:0F**********************************@microsof t.com...
Thanks a lot. I'll try the two different methods (callbyname and
Propertydescriptor) and see how much faster the PropertyDescriptor is.
Just
curious as to why you made the m_Ascending a ReadOnly since it's private
anyway and can't be accessed outside the class.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
> The major drawback, I think, is speed.

Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class
>> >> > dim C as type = type.GetType(myarraylist(0))

Dim mycomparer as new mycombare(C, col, True)
>> > myArrayList.Sort(mycomparer)


Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
> You are, of course as usual, correct. I was just trying to simpify my
> explaination. The major drawback, I think, is speed. I probably would
> be
> faster to use the object with properties directly and use late binding
> rather
> than CallbyName. But anyway, it's pretty fast for small arraylists,
> arrays,
> etc. Thanks again for your help.
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> Actually your code will work on two objects of different types as long
>> as
>> they have the same property names.
>>
>> For example, your class will compare the these two classes without any
>> problems:
>>
>> Public Class Class1
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Public Class Class2
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Jay
>>
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:E1**********************************@microsof t.com...
>> > Thanks Jay and Cor. I was thinking about the CallbyName but I
>> > didn't
>> > know
>> > it
>> > would work with a general arraylist of classes. Following is what I
>> > ended
>> > up
>> > with that will sort any arraylist of classes (must be same class
>> > types)
>> > by
>> > any string or integer or decimal property of the class in ascending
>> > or
>> > descending order:
>> >
>> > dim myArrayList as ArrayList
>> > 'Set each element of the ArrayList to any class (must all be of same
>> > type)
>> > Dim mycomparer As New mycompare
>> >
>> > mycomparer.propertyname = col
>> > mycomparer.ascending = True
>> > myArrayList.Sort(mycomparer)
>> > .......
>> > .......
>> > __________________________________________________ ________________
>> > Protected Class mycompare
>> > Implements IComparer
>> > Public propertyname As String
>> > Public ascending As Boolean
>> > Private Function Compare(ByVal x As Object, ByVal y As Object) As
>> > Integer
>> > _ Implements IComparer.Compare
>> > If ascending Then
>> > Return New CaseInsensitiveComparer().Compare(CallByName(x,
>> > _
>> > propertyname, CallType.Get), CallByName(y, propertyname, _
>> > CallType.Get))
>> > Else
>> > Return New CaseInsensitiveComparer().Compare(CallByName(y,
>> > _
>> > propertyname, CallType.Get), CallByName(x, propertyname, _
>> > CallType.Get))
>> > End If
>> > End Function
>> > End Class
>> > __________________________________________________ _____________
>> >
>> > "Jay B. Harlow [MVP - Outlook]" wrote:
>> >
>> >> Dennis,
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >>
>> >> You cannot cast based on a Type variable, the DirectCast needs the
>> >> name
>> >> (myclass) of the type at compile time.
>> >>
>> >> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> >> the
>> >> "easist" way is to use CallByName
>> >>
>> >> Dim o As Object = CallByName(list(0), "MyProperty",
>> >> CallType.Get)
>> >>
>> >>
>> >> Alternatively I will use a PropertyDescriptor or Reflection.
>> >>
>> >> Something like:
>> >>
>> >> Dim properties As
>> >> System.ComponentModel.PropertyDescriptorCollection
>> >> properties =
>> >> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>> >>
>> >> Dim o As Object =
>> >> properties("MyProperty").GetValue(list(0))
>> >>
>> >> However I normally only use PropertyDescriptor in more advanced
>> >> cases...
>> >>
>> >> Hope this helps
>> >> Jay
>> >>
>> >> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> >> news:1F**********************************@microsof t.com...
>> >> >I have a class named "myclass" and an arraylist containing
>> >> >elements
>> >> >of
>> >> >type
>> >> > "MyClass". I want to get the value of a property of "MyClass" (a
>> >> > string
>> >> > type) for one of the arraylist elements.
>> >> >
>> >> > I can get this using:
>> >> > dim b as string
>> >> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >> >
>> >> > However, I want to use an object to define the type "MyClass"
>> >> > like:
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >> >
>> >> > but I get a "c" type not defined. How can I do this?
>> >> >
>> >> > Thanks for any help.
>> >> >
>> >> >
>> >> > --
>> >> > Dennis in Houston
>> >>
>> >>
>> >>
>>
>>
>>


Nov 21 '05 #12

P: n/a
I tried the PropertyDescriptor route and I found two things;

1) I had to add ".GeType.ToString" in use dim c as type =
type.GetType(myarraylist(0).GetType.ToString) to get it to compile

2) I get an error when it tries to sort in the
x=m_Property.GetValue(propertyName) that just says unhandled exception in
Icompare.

Any idea what is going on?

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
The major drawback, I think, is speed.

Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class
>> > dim C as type = type.GetType(myarraylist(0)) Dim mycomparer as new mycombare(C, col, True) > myArrayList.Sort(mycomparer)


Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
You are, of course as usual, correct. I was just trying to simpify my
explaination. The major drawback, I think, is speed. I probably would be
faster to use the object with properties directly and use late binding
rather
than CallbyName. But anyway, it's pretty fast for small arraylists,
arrays,
etc. Thanks again for your help.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
Actually your code will work on two objects of different types as long as
they have the same property names.

For example, your class will compare the these two classes without any
problems:

Public Class Class1

Public ReadOnly Property Test() As String
...

End Class

Public Class Class2

Public ReadOnly Property Test() As String
...

End Class

Jay
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:E1**********************************@microsof t.com...
> Thanks Jay and Cor. I was thinking about the CallbyName but I didn't
> know
> it
> would work with a general arraylist of classes. Following is what I
> ended
> up
> with that will sort any arraylist of classes (must be same class types)
> by
> any string or integer or decimal property of the class in ascending or
> descending order:
>
> dim myArrayList as ArrayList
> 'Set each element of the ArrayList to any class (must all be of same
> type)
> Dim mycomparer As New mycompare
>
> mycomparer.propertyname = col
> mycomparer.ascending = True
> myArrayList.Sort(mycomparer)
> .......
> .......
> __________________________________________________ ________________
> Protected Class mycompare
> Implements IComparer
> Public propertyname As String
> Public ascending As Boolean
> Private Function Compare(ByVal x As Object, ByVal y As Object) As
> Integer
> _ Implements IComparer.Compare
> If ascending Then
> Return New CaseInsensitiveComparer().Compare(CallByName(x, _
> propertyname, CallType.Get), CallByName(y, propertyname, _
> CallType.Get))
> Else
> Return New CaseInsensitiveComparer().Compare(CallByName(y, _
> propertyname, CallType.Get), CallByName(x, propertyname, _
> CallType.Get))
> End If
> End Function
> End Class
> __________________________________________________ _____________
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> > dim C as type = type.GetType(myarraylist(0))
>> > b = DirectCast(myarraylist(0), C ).MyProperty
>>
>> You cannot cast based on a Type variable, the DirectCast needs the
>> name
>> (myclass) of the type at compile time.
>>
>> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> the
>> "easist" way is to use CallByName
>>
>> Dim o As Object = CallByName(list(0), "MyProperty", CallType.Get)
>>
>>
>> Alternatively I will use a PropertyDescriptor or Reflection.
>>
>> Something like:
>>
>> Dim properties As
>> System.ComponentModel.PropertyDescriptorCollection
>> properties =
>> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>>
>> Dim o As Object = properties("MyProperty").GetValue(list(0))
>>
>> However I normally only use PropertyDescriptor in more advanced
>> cases...
>>
>> Hope this helps
>> Jay
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:1F**********************************@microsof t.com...
>> >I have a class named "myclass" and an arraylist containing elements
>> >of
>> >type
>> > "MyClass". I want to get the value of a property of "MyClass" (a
>> > string
>> > type) for one of the arraylist elements.
>> >
>> > I can get this using:
>> > dim b as string
>> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >
>> > However, I want to use an object to define the type "MyClass" like:
>> > dim C as type = type.GetType(myarraylist(0))
>> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >
>> > but I get a "c" type not defined. How can I do this?
>> >
>> > Thanks for any help.
>> >
>> >
>> > --
>> > Dennis in Houston
>>
>>
>>


Nov 21 '05 #13

P: n/a
Dennis,
I suspect #2 is caused by #1.

I copied #1 from your original post. It should read:

Dim c As Type = myarraylist(0).GetType()

Or perferable:
Dim c As Type = GetType(AnyClass)

Where AnyClass is the class name of the objects you are putting into the
ArrayList.

Something like:

Public Class Class1

Public ReadOnly m_test As String

Public Sub New(ByVal test As String)
m_test = test
End Sub
Public ReadOnly Property Test() As String
Get
Return m_test
End Get
End Property

End Class

Public Shared Sub Main()
Dim myarraylist As New ArrayList
myarraylist.Add(New Class1("A"))
myarraylist.Add(New Class1("B"))
myarraylist.Add(New Class1("C"))

Const col As String = "Test"

Dim C As Type = GetType(Class1)

Dim mycomparer As New mycompare(C, col, True)
myarraylist.Sort(mycomparer)

Application.EnableVisualStyles()
Application.DoEvents()
Application.Run(New MainForm)
End Sub

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:80**********************************@microsof t.com...
I tried the PropertyDescriptor route and I found two things;

1) I had to add ".GeType.ToString" in use dim c as type =
type.GetType(myarraylist(0).GetType.ToString) to get it to compile

2) I get an error when it tries to sort in the
x=m_Property.GetValue(propertyName) that just says unhandled exception in
Icompare.

Any idea what is going on?

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
> The major drawback, I think, is speed.

Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class
>> >> > dim C as type = type.GetType(myarraylist(0))

Dim mycomparer as new mycombare(C, col, True)
>> > myArrayList.Sort(mycomparer)


Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
> You are, of course as usual, correct. I was just trying to simpify my
> explaination. The major drawback, I think, is speed. I probably would
> be
> faster to use the object with properties directly and use late binding
> rather
> than CallbyName. But anyway, it's pretty fast for small arraylists,
> arrays,
> etc. Thanks again for your help.
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> Actually your code will work on two objects of different types as long
>> as
>> they have the same property names.
>>
>> For example, your class will compare the these two classes without any
>> problems:
>>
>> Public Class Class1
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Public Class Class2
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Jay
>>
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:E1**********************************@microsof t.com...
>> > Thanks Jay and Cor. I was thinking about the CallbyName but I
>> > didn't
>> > know
>> > it
>> > would work with a general arraylist of classes. Following is what I
>> > ended
>> > up
>> > with that will sort any arraylist of classes (must be same class
>> > types)
>> > by
>> > any string or integer or decimal property of the class in ascending
>> > or
>> > descending order:
>> >
>> > dim myArrayList as ArrayList
>> > 'Set each element of the ArrayList to any class (must all be of same
>> > type)
>> > Dim mycomparer As New mycompare
>> >
>> > mycomparer.propertyname = col
>> > mycomparer.ascending = True
>> > myArrayList.Sort(mycomparer)
>> > .......
>> > .......
>> > __________________________________________________ ________________
>> > Protected Class mycompare
>> > Implements IComparer
>> > Public propertyname As String
>> > Public ascending As Boolean
>> > Private Function Compare(ByVal x As Object, ByVal y As Object) As
>> > Integer
>> > _ Implements IComparer.Compare
>> > If ascending Then
>> > Return New CaseInsensitiveComparer().Compare(CallByName(x,
>> > _
>> > propertyname, CallType.Get), CallByName(y, propertyname, _
>> > CallType.Get))
>> > Else
>> > Return New CaseInsensitiveComparer().Compare(CallByName(y,
>> > _
>> > propertyname, CallType.Get), CallByName(x, propertyname, _
>> > CallType.Get))
>> > End If
>> > End Function
>> > End Class
>> > __________________________________________________ _____________
>> >
>> > "Jay B. Harlow [MVP - Outlook]" wrote:
>> >
>> >> Dennis,
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >>
>> >> You cannot cast based on a Type variable, the DirectCast needs the
>> >> name
>> >> (myclass) of the type at compile time.
>> >>
>> >> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> >> the
>> >> "easist" way is to use CallByName
>> >>
>> >> Dim o As Object = CallByName(list(0), "MyProperty",
>> >> CallType.Get)
>> >>
>> >>
>> >> Alternatively I will use a PropertyDescriptor or Reflection.
>> >>
>> >> Something like:
>> >>
>> >> Dim properties As
>> >> System.ComponentModel.PropertyDescriptorCollection
>> >> properties =
>> >> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>> >>
>> >> Dim o As Object =
>> >> properties("MyProperty").GetValue(list(0))
>> >>
>> >> However I normally only use PropertyDescriptor in more advanced
>> >> cases...
>> >>
>> >> Hope this helps
>> >> Jay
>> >>
>> >> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> >> news:1F**********************************@microsof t.com...
>> >> >I have a class named "myclass" and an arraylist containing
>> >> >elements
>> >> >of
>> >> >type
>> >> > "MyClass". I want to get the value of a property of "MyClass" (a
>> >> > string
>> >> > type) for one of the arraylist elements.
>> >> >
>> >> > I can get this using:
>> >> > dim b as string
>> >> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >> >
>> >> > However, I want to use an object to define the type "MyClass"
>> >> > like:
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >> >
>> >> > but I get a "c" type not defined. How can I do this?
>> >> >
>> >> > Thanks for any help.
>> >> >
>> >> >
>> >> > --
>> >> > Dennis in Houston
>> >>
>> >>
>> >>
>>
>>
>>


Nov 21 '05 #14

P: n/a
Dennis,

And why can you than not use my solution?

Unlucky it can not in a select case because then it would be even more easy
to use.

Cor
Nov 21 '05 #15

P: n/a
Dennis,
I should add, that the PropertyDescriptor solution requires that all the
classes (in a single ArrayList) be the same type (it can be a common base
type).

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:80**********************************@microsof t.com...
I tried the PropertyDescriptor route and I found two things;

1) I had to add ".GeType.ToString" in use dim c as type =
type.GetType(myarraylist(0).GetType.ToString) to get it to compile

2) I get an error when it tries to sort in the
x=m_Property.GetValue(propertyName) that just says unhandled exception in
Icompare.

Any idea what is going on?

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
> The major drawback, I think, is speed.

Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class
>> >> > dim C as type = type.GetType(myarraylist(0))

Dim mycomparer as new mycombare(C, col, True)
>> > myArrayList.Sort(mycomparer)


Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
> You are, of course as usual, correct. I was just trying to simpify my
> explaination. The major drawback, I think, is speed. I probably would
> be
> faster to use the object with properties directly and use late binding
> rather
> than CallbyName. But anyway, it's pretty fast for small arraylists,
> arrays,
> etc. Thanks again for your help.
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> Actually your code will work on two objects of different types as long
>> as
>> they have the same property names.
>>
>> For example, your class will compare the these two classes without any
>> problems:
>>
>> Public Class Class1
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Public Class Class2
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Jay
>>
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:E1**********************************@microsof t.com...
>> > Thanks Jay and Cor. I was thinking about the CallbyName but I
>> > didn't
>> > know
>> > it
>> > would work with a general arraylist of classes. Following is what I
>> > ended
>> > up
>> > with that will sort any arraylist of classes (must be same class
>> > types)
>> > by
>> > any string or integer or decimal property of the class in ascending
>> > or
>> > descending order:
>> >
>> > dim myArrayList as ArrayList
>> > 'Set each element of the ArrayList to any class (must all be of same
>> > type)
>> > Dim mycomparer As New mycompare
>> >
>> > mycomparer.propertyname = col
>> > mycomparer.ascending = True
>> > myArrayList.Sort(mycomparer)
>> > .......
>> > .......
>> > __________________________________________________ ________________
>> > Protected Class mycompare
>> > Implements IComparer
>> > Public propertyname As String
>> > Public ascending As Boolean
>> > Private Function Compare(ByVal x As Object, ByVal y As Object) As
>> > Integer
>> > _ Implements IComparer.Compare
>> > If ascending Then
>> > Return New CaseInsensitiveComparer().Compare(CallByName(x,
>> > _
>> > propertyname, CallType.Get), CallByName(y, propertyname, _
>> > CallType.Get))
>> > Else
>> > Return New CaseInsensitiveComparer().Compare(CallByName(y,
>> > _
>> > propertyname, CallType.Get), CallByName(x, propertyname, _
>> > CallType.Get))
>> > End If
>> > End Function
>> > End Class
>> > __________________________________________________ _____________
>> >
>> > "Jay B. Harlow [MVP - Outlook]" wrote:
>> >
>> >> Dennis,
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >>
>> >> You cannot cast based on a Type variable, the DirectCast needs the
>> >> name
>> >> (myclass) of the type at compile time.
>> >>
>> >> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> >> the
>> >> "easist" way is to use CallByName
>> >>
>> >> Dim o As Object = CallByName(list(0), "MyProperty",
>> >> CallType.Get)
>> >>
>> >>
>> >> Alternatively I will use a PropertyDescriptor or Reflection.
>> >>
>> >> Something like:
>> >>
>> >> Dim properties As
>> >> System.ComponentModel.PropertyDescriptorCollection
>> >> properties =
>> >> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>> >>
>> >> Dim o As Object =
>> >> properties("MyProperty").GetValue(list(0))
>> >>
>> >> However I normally only use PropertyDescriptor in more advanced
>> >> cases...
>> >>
>> >> Hope this helps
>> >> Jay
>> >>
>> >> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> >> news:1F**********************************@microsof t.com...
>> >> >I have a class named "myclass" and an arraylist containing
>> >> >elements
>> >> >of
>> >> >type
>> >> > "MyClass". I want to get the value of a property of "MyClass" (a
>> >> > string
>> >> > type) for one of the arraylist elements.
>> >> >
>> >> > I can get this using:
>> >> > dim b as string
>> >> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >> >
>> >> > However, I want to use an object to define the type "MyClass"
>> >> > like:
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >> >
>> >> > but I get a "c" type not defined. How can I do this?
>> >> >
>> >> > Thanks for any help.
>> >> >
>> >> >
>> >> > --
>> >> > Dennis in Houston
>> >>
>> >>
>> >>
>>
>>
>>


Nov 21 '05 #16

P: n/a
Jay, I got it working. You'll never believe what the real problem was. I
was passing the property name as I had specified it which was "Col1". The
propertyDescriptor converted it to lower case, i.e., "col1". When I passed
the lower case to the Icomparer routine, it works great. Thanks a lot for
you help.

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
I should add, that the PropertyDescriptor solution requires that all the
classes (in a single ArrayList) be the same type (it can be a common base
type).

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:80**********************************@microsof t.com...
I tried the PropertyDescriptor route and I found two things;

1) I had to add ".GeType.ToString" in use dim c as type =
type.GetType(myarraylist(0).GetType.ToString) to get it to compile

2) I get an error when it tries to sort in the
x=m_Property.GetValue(propertyName) that just says unhandled exception in
Icompare.

Any idea what is going on?

"Jay B. Harlow [MVP - Outlook]" wrote:
Dennis,
> The major drawback, I think, is speed.
Which is where I would consider using a PropertyDescriptor instead of
CallByName in this case...

Something like:

Protected Class mycompare
Implements IComparer

Private ReadOnly m_property As
System.ComponentModel.PropertyDescriptor
Private ReadOnly m_ascending As Boolean

Public Sub New(ByVal componentType As Type, ByVal propertyName As
String, ByVal ascending As Boolean)
Dim properties As
System.ComponentModel.PropertyDescriptorCollection
properties =
System.ComponentModel.TypeDescriptor.GetProperties (componentType)
m_property = properties(propertyName)
m_ascending = ascending
End Sub

Private Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements IComparer.Compare
x = m_property.GetValue(x)
y = m_property.GetValue(y)
If m_ascending Then
Return New CaseInsensitiveComparer().Compare(x, y)
Else
Return New CaseInsensitiveComparer().Compare(y, x)
End If
End Function

End Class

>> >> > dim C as type = type.GetType(myarraylist(0))
Dim mycomparer as new mycombare(C, col, True)
>> > myArrayList.Sort(mycomparer)

Hope this helps
Jay

"Dennis" <De****@discussions.microsoft.com> wrote in message
news:71**********************************@microsof t.com...
> You are, of course as usual, correct. I was just trying to simpify my
> explaination. The major drawback, I think, is speed. I probably would
> be
> faster to use the object with properties directly and use late binding
> rather
> than CallbyName. But anyway, it's pretty fast for small arraylists,
> arrays,
> etc. Thanks again for your help.
>
> "Jay B. Harlow [MVP - Outlook]" wrote:
>
>> Dennis,
>> Actually your code will work on two objects of different types as long
>> as
>> they have the same property names.
>>
>> For example, your class will compare the these two classes without any
>> problems:
>>
>> Public Class Class1
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Public Class Class2
>>
>> Public ReadOnly Property Test() As String
>> ...
>>
>> End Class
>>
>> Jay
>>
>>
>> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> news:E1**********************************@microsof t.com...
>> > Thanks Jay and Cor. I was thinking about the CallbyName but I
>> > didn't
>> > know
>> > it
>> > would work with a general arraylist of classes. Following is what I
>> > ended
>> > up
>> > with that will sort any arraylist of classes (must be same class
>> > types)
>> > by
>> > any string or integer or decimal property of the class in ascending
>> > or
>> > descending order:
>> >
>> > dim myArrayList as ArrayList
>> > 'Set each element of the ArrayList to any class (must all be of same
>> > type)
>> > Dim mycomparer As New mycompare
>> >
>> > mycomparer.propertyname = col
>> > mycomparer.ascending = True
>> > myArrayList.Sort(mycomparer)
>> > .......
>> > .......
>> > __________________________________________________ ________________
>> > Protected Class mycompare
>> > Implements IComparer
>> > Public propertyname As String
>> > Public ascending As Boolean
>> > Private Function Compare(ByVal x As Object, ByVal y As Object) As
>> > Integer
>> > _ Implements IComparer.Compare
>> > If ascending Then
>> > Return New CaseInsensitiveComparer().Compare(CallByName(x,
>> > _
>> > propertyname, CallType.Get), CallByName(y, propertyname, _
>> > CallType.Get))
>> > Else
>> > Return New CaseInsensitiveComparer().Compare(CallByName(y,
>> > _
>> > propertyname, CallType.Get), CallByName(x, propertyname, _
>> > CallType.Get))
>> > End If
>> > End Function
>> > End Class
>> > __________________________________________________ _____________
>> >
>> > "Jay B. Harlow [MVP - Outlook]" wrote:
>> >
>> >> Dennis,
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >>
>> >> You cannot cast based on a Type variable, the DirectCast needs the
>> >> name
>> >> (myclass) of the type at compile time.
>> >>
>> >> If you truly want to get AnyProperty form an ArrayList of AnyClass,
>> >> the
>> >> "easist" way is to use CallByName
>> >>
>> >> Dim o As Object = CallByName(list(0), "MyProperty",
>> >> CallType.Get)
>> >>
>> >>
>> >> Alternatively I will use a PropertyDescriptor or Reflection.
>> >>
>> >> Something like:
>> >>
>> >> Dim properties As
>> >> System.ComponentModel.PropertyDescriptorCollection
>> >> properties =
>> >> System.ComponentModel.TypeDescriptor.GetProperties (list(0))
>> >>
>> >> Dim o As Object =
>> >> properties("MyProperty").GetValue(list(0))
>> >>
>> >> However I normally only use PropertyDescriptor in more advanced
>> >> cases...
>> >>
>> >> Hope this helps
>> >> Jay
>> >>
>> >> "Dennis" <De****@discussions.microsoft.com> wrote in message
>> >> news:1F**********************************@microsof t.com...
>> >> >I have a class named "myclass" and an arraylist containing
>> >> >elements
>> >> >of
>> >> >type
>> >> > "MyClass". I want to get the value of a property of "MyClass" (a
>> >> > string
>> >> > type) for one of the arraylist elements.
>> >> >
>> >> > I can get this using:
>> >> > dim b as string
>> >> > b = DirectCast(myarraylist(0),myclass).myproperty
>> >> >
>> >> > However, I want to use an object to define the type "MyClass"
>> >> > like:
>> >> > dim C as type = type.GetType(myarraylist(0))
>> >> > b = DirectCast(myarraylist(0), C ).MyProperty
>> >> >
>> >> > but I get a "c" type not defined. How can I do this?
>> >> >
>> >> > Thanks for any help.
>> >> >
>> >> >
>> >> > --
>> >> > Dennis in Houston
>> >>
>> >>
>> >>
>>
>>
>>


Nov 21 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.