Is there a way to find all classes (In fact, all instances) which implement a given Interface?
I are thinking of force the interface to add a reference of himself to a global array.
Each .new() constructor of each class should run the interface routine to add the instance being initialized to a shared global array.
But it looks like an interface cannot be defined with a shared variable (is not a class), so I gonna need to add a new data definition, which can be trouble to track is related to the interface, and worst, it would clutter my code.
Probably exist a better way.
Some tips?
Scott.Macmaster
December 29th, 2008, 07:41 PM
This seems like a very unusually requirement and probably a bad design. If you give some more details I could suggest a better alternative. In the meantime I have a suggestion for adding all instances to a global variable. However, there are 2 major issues with this. Someone could create a local instance of the global object. Also, this would result in major memory leaks if you aren't careful about removing references to unused instances of the objects you are tracking.
Public Class Tracker
Private Instances As List(Of SpecialClass)
Public Sub Add(ByVal obj As SpecialClass)
Instances.Add(obj)
End Sub
End Class
Public Class SpecialClass
Private Sub New()
End Sub
Public Shared Function GiveMeANewOne(ByVal tracker As Tracker) As SpecialClass
Dim obj As New SpecialClass()
tracker.Add(obj)
Return obj
End Function
End Class
If you implement ths in a dll you should be able to prevent creation of local Trackers. However, you still have the issue of memory leaks.
Marraco
December 30th, 2008, 07:57 AM
This seems like a very unusually requirement and probably a bad design.I agree, bad design. But I don't know how to do it the "right" way. If you give some more details I could suggest a better alternative. I Read data from a file. I organize read data in groups Data A, Data B, ... Data N.
Each Data X may be processed by different classes like Class X, Class Y, Class Z. Is each class who defines if it need to process a given kind of data, and many unrelated class can process the same data (or portion of that data).
I want to add a new class, and automatically have it capable of process Data N by defining a Interface FunctionForDataN for process of Data N.
The basic idea was, make each Data N to search for any class . If her supports an Interface FunctionForDataN, then execute that Interface.
I have no Idea on how to do it. I had searched on Reflection, but got no useful solution.
I had implemented a .Register() sub on the Interface FunctionForDataN, so each class implementing that Interface, should call the .Register function on his .New constructor, passing a Delegate to the local interface implementation.In the meantime I have a suggestion for adding all instances to a global variable. However, there are 2 major issues with this. Someone could create a local instance of the global object. Also, this would result in major memory leaks if you aren't careful about removing references to unused instances of the objects you are tracking.
...
If you implement ths in a dll you should be able to prevent creation of local Trackers. However, you still have the issue of memory leaks.Memory leaks. I had not think on it. Maybe I should add a .Dispose routine to .Unregister
Scott.Macmaster
December 30th, 2008, 07:08 PM
The garbage collector in .Net will only free up the memory used by objects after the last reference to the object is removed. I assume your Unregister() method removes references from a list so there's nothing else you can add to that to deal with memory leaks. I'm not sure what you mean by adding Dispose to it. Dispose is a required function for objects that implement IDisposable. But that doesn't guarantee cleanup if you forget to call Unregister() for every object. You could wrap that in a Using/End Using. However, you still have to remember to use Using/End Using each time. I'm still not sure what you are trying to do. However, I don't think tracking all these objects is the solution.
I briefly looked at the members of the garbage collector but I don't see anything that would list all the objects it's managing. If there was you could loop through and find all instances of your object. However, you should leave the GC along. It works just fine unless your doing something bad.
Reflection won't help at all since it's job is to examine data types. It doesn't do anything with instances of objects.
I kinda' get the impression that you are loading a file that list instructions for doing things. Maybe the following code will help.
Public Class Instructions
Public Instructions As New List(Of Instruction)
Public Sub ProcessInstructions()
For Each Instruction In Instructions
Instruction.ProcessData()
Next
End Sub
End Class
Public MustInherit Class Instruction
Protected Data As String
Public MustOverride Sub ProcessData()
End Class
Public Class Soup
Inherits Instruction
Public Overrides Sub ProcessData()
If Data = "Chicken" Then
MakeChickenSoup()
End If
End Sub
End Class
Marraco
January 1st, 2009, 09:12 AM
The garbage collector in .Net will only free up the memory used by objects after the last reference to the object is removed. I assume your Unregister() method removes references from a list so there's nothing else you can add to that to deal with memory leaks. I'm not sure what you mean by adding Dispose to it. Dispose is a required function for objects that implement IDisposable.I added Implements IDisposable to the user base class for processing data:
Public Interface IFunctionForDataN
Sub Register()
...
Sub UnRegister()
End Interface 'IFunctionForDataN
Public MustInherit Class ValidateFileData
Implements IDisposable
Implements IFunctionForDataN
#Region " IFunctionForDataN "
Sub New()
...
Register()
End Sub
... 'Another interface code
MustOverride Sub Register()... adding MyDelegates to an ICollection
...
MustOverride Sub UnRegister()... Deleting MyDelegates from ICollection
#End Region '" IFunctionForDataN "
...
#Region " IDisposable Support "
Protected disposedValue As Boolean = False ' To detect redundant calls
Protected Sub Dispose(ByVal disposing As Boolean)
Unregister()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region '" IDisposable Support "
...
End Class 'ValidateFileData(Not sure on what to do with disposedValue variable. :confused:)
But that doesn't guarantee cleanup if you forget to call Unregister() for every object. You could wrap that in a Using/End Using. However, you still have to remember to use Using/End Using each time. I'm still not sure what you are trying to do. However, I don't think tracking all these objects is the solution.
...
:thumb:I like your idea on GiveMeANewOne() this wayPublic Class SpecialClass
Inherits ValidateFileData
...
Public Shared Function GiveMeANewOne(ByVal Parameters As SpecialClass.SpecialParameters) As SpecialClass
Dim obj As New SpecialClass(Parameters)
obj.Register()
Return obj
End Function
End ClassBecause My New() on my Base class, although nicely .Register() automatically any inherited class, does not allow me to override or overload the .New() constructor, and forces me to put MyBase.New() only as the first line on the children .New(). It does not let me pass arbitrary parameters to the constructor, to initialize variables before registering.
The bad side of it, is that I can forget to add the obj.Register() line.
The Interface IFunctionForDataN, with [MustInherit] MustOverride Sub Register() warrant that I never would forget to write the Register() sub, -Otherwise, .NET would kick my *** until I write them- but nothing warrant that I would add the obj.Register() line on Function GiveMeANewOne.
TheCPUWizard
January 1st, 2009, 10:47 AM
Remember two "rules"
1) It MUST be safe to call Dispose() on an instance multiple times.
2) It is suggested that accessing any method (other than disposed) or propertyy on a disposed object throw an ObjectDisposed() exception.
This answers your qeustion about what to do with the variable. ;)
Marraco
January 1st, 2009, 11:13 AM
Remember two "rules"
1) It MUST be safe to call Dispose() on an instance multiple times.
2) It is suggested that accessing any method (other than disposed) or propertyy on a disposed object throw an ObjectDisposed() exception.
This answers your qeustion about what to do with the variable. ;)Did it mean something like this?:
#Region " IDisposable Support "
Protected disposedValue As Boolean = False ' To detect redundant calls
Protected Sub Dispose(ByVal disposing As Boolean)
Unregister()
disposedValue = true
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region '" IDisposable Support "
And then adding to any public function/sub/property?:
If disposedValue Then Throw New ObjectDisposedException("AArrrgg")
TheCPUWizard
January 1st, 2009, 11:18 AM
Did it mean something like this....
And what exactly happens when the following code is called TWICE:
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Marraco
January 1st, 2009, 12:22 PM
And what exactly happens when the following code is called TWICE:I guess, it should be:
Public Sub Dispose() Implements IDisposable.Dispose
If disposedValue Then
Throw New ObjectDisposedException("AArrrgg")
else
Dispose(True)
GC.SuppressFinalize(Me)
End If
End SubżIts right?
(I need to read more about this stuff)
TheCPUWizard
January 1st, 2009, 12:30 PM
I guess, it should be:
You guessed wrong. Go back and reat Reul #1 (In reply #6)
TheCPUWizard
January 1st, 2009, 12:32 PM
The garbage collector in .Net will only free up the memory used by objects after the last reference to the object is removed. I assume your Unregister() method removes references from a list so there's nothing else you can add to that to deal with memory leaks. I'm not sure what you mean by adding Dispose to it. Dispose is a required function for objects that implement IDisposable. But that doesn't guarantee cleanup if you forget to call Unregister() for every object. You could wrap that in a Using/End Using. However, you still have to remember to use Using/End Using each time. I'm still not sure what you are trying to do. However, I don't think tracking all these objects is the solution.
For objects which have meaningful Dispose implementations (this one does not seem to), the following can be used ON DEVELOPMENT BUILDS to validate the usage...
1) Make sure that Dispose() causes a GC.SuppressFinalize() call. (It always should!)
2) Have the Finalizer (which should never be invoked) record the fact in some manner (Exception, LogFile, ext). Just be carefuly to handle the "AppDomain teardown" condition.
Marraco
January 1st, 2009, 01:05 PM
1) It MUST be safe to call Dispose() on an instance multiple times.
...As I see, the only unsafe thing it can occur, is a repeated calling to UnRegister(), because, it may try to operate on data that was modified/destroyed/disposed at the before UnRegister() Call.
I suppose that UnRegister destroy any external reference to my internal Class data.
Register call another class, to accept a delegate as parameter. (Is only stored on an List(Of DelegateType))
UnRegister call the same Class to erase that delegate, and is That class who should warrant, deleting any copy of data received (I think it haves only one copy)
Is not clear if is safe to call GC.SuppressFinalize(Me) again.
Scott.Macmaster
January 1st, 2009, 07:44 PM
The details of using IDisposable are irrelevant here. Unless you left something out everything you have is managed code. Basically, you have a list contained in a class. The system will automatically free the memory. Because of that you don't need Unreqister(). You don't really need Register(). Unless you're doing additional processing there, just add the object to the list and drop the call to Register().
I'm not sure what you are trying to do here. From your first description it sounds like you are loading data then passing each chunk of data to one or more objects. These objects then not only do processing on their data but also on data from other objects. Creating a highly complicated level of coupling.
I'd suggest a more hierarchical approach. Maybe I could offer a suggestion if you tried to explain what this data is and what you are trying to do with it.
Scott
TheCPUWizard
January 1st, 2009, 08:02 PM
The details of using IDisposable are irrelevant here.
Depends on your point of view. I 100% agree with Disposable not being germane to the problem
For objects which have meaningful Dispose implementations (this one does not seem to),
But IF IDisposable is implemented, then an incorrect implementation will only cause additional problems. [While a correct one will have no net impact on the situation]
Marraco
January 2nd, 2009, 08:08 AM
The details of using IDisposable are irrelevant here. Unless you left something out everything you have is managed code. Basically, you have a list contained in a class. The system will automatically free the memory. Because of that you don't need Unreqister(). You don't really need Register(). Unless you're doing additional processing there, just add the object to the list and drop the call to Register().
I'm not sure what you are trying to do here. From your first description it sounds like you are loading data then passing each chunk of data to one or more objects. These objects then not only do processing on their data but also on data from other objects. Creating a highly complicated level of coupling.
I'd suggest a more hierarchical approach. Maybe I could offer a suggestion if you tried to explain what this data is and what you are trying to do with it.This is a description of the frame. It write it only as information:
I are updating an VB6 application, to VB.NET. I are totally reengineering it because it was full of bugs.
So, I have the new application separated on a number of classes, and his inherited classes. They can grow, and I can make new ones, as I continue upgrading the VB6 app.
So, now, I have this situation:
I have a text file, Since it was inherited from a VB6 application, it can be edited by user. And users are prone to make mistakes.
So, at load times, an undefined number of classes need to check each read data, to check for validity. If a given line of the text file is not valid, the class checking it need to:
- Say that it is not valid.
- Say Why is not valid.
- Give an user readable text to advice the user (or to be stored in a log file).
- Adopt some measure to manage the data if is not totally broken.
- Flag the data as invalidated, so no other class uses it, expecting it to work.
In the VB6 version, the same routine that readed the file was doing all the checking, but that was prone to bugs, because the classes that really use the data where unrelated to the checkings, and changing anything in some class generated bugs on the reading routine.
So, now each class is responsible for managing anything that should be internal, as checking for data validity from his own viewpoint.
I implemented the validation code as an Interface.
The interface defines a delegate who need to have each class capable of Checking.
The Interface defines a boolean function to tell If a given class implementing it should check a given line of data.
Also defines a function .Register(), because i have "no idea" (and I think is good to assume it) who, or how many classes would implement that Interface, so each class need to add a delegate to a common Interface array, to the file, after reading each line, can find all the classes who can manage it, and run his Checking routines. This is my basic problem. I don't know what classes implement the interface, and I want to automate it as much as possible, so I reduce future coding, and I want to the .NET environment to kick my azz if I forget to implement a key routine.
For that reason, I need the .Register interface function, who add delegates to a common array.
now, Macmaster post (... this would result in major memory leaks ...)
The problem is, what if a given instance of a class stops existing? (I think no one should stop existing, but want no to leave broken tips on the code), so, it need to have an unregister function.
Since I read on Internet that I should implement the .Dispose routine, to have the Unregister function automatically executed, then, as I understood, any class capable of unregister automatically should implement the IDisposable interface. When you write "Implements Idisposable", the .NET environment automatically add this code:
Public Class UnregisterCapable
Implements IDisposable
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free other state (managed objects).
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End ClassSo, I need to fill in the blanks.
Marraco
January 2nd, 2009, 08:21 AM
...So, I need to fill in the blanks.The delegate in the common array is the unique connection between the class who manage the files, and any other class, so the unique thing that UnRegister function does, is to delete the delegate from the common array.
Marraco
January 2nd, 2009, 09:28 AM
...
I'm not sure what you are trying to do here. From your first description it sounds like you are loading data then passing each chunk of data to one or more objects...I think that Explaining more would make more noise than help, but this is a bare bones skeleton of my code:
Imports WindowsApplication1.MyModule.FileLoader
Imports WindowsApplication1.MyModule.FileLoader.ValidationResult
Public Class Form1
'...
End Class
Public Module MyModule
Public Class FileLoader
Public Shared ValidatorsList As New PersonalizedList(Of Validator)
Public Delegate Function Validator(ByRef ThisLine As ReadData) As ValidationResult
Public Class PersonalizedList(Of Type)
Inherits SortedList
Public Function GetValidKeys() As String()
'...
End Function
Public Sub validate()
'...
End Sub
Public Sub Add(ByVal SomeDelegate As Validator)
'...
End Sub
Public Sub Remove(ByVal SomeDelegate As Validator)
'...
End Sub
End Class
Public MustInherit Class ValidationResult
Public Structure ReadData
'...
End Structure
Public MustOverride Function ShouldValidate() As Boolean
Public MustOverride Sub Validate()
End Class
Public Interface IValidatorInterface
Sub Register()
Sub UnRegister()
End Interface
'All This mess is to call this
Public Sub New(ByVal FileName As File)
For Each Line In FileName
For Each Key In ValidatorsList.GetValidKeys(Line)
ValidatorsList(Key).Validate()
Next
Next Line
End Sub
End Class
Public Class SomeClass
Implements IValidatorInterface
Implements IDisposable
Public Sub Register() Implements FileLoader.IValidatorInterface.Register
ValidatorsList.Add(AddressOf MyClassValidator)
End Sub
Public Sub UnRegister() Implements FileLoader.IValidatorInterface.UnRegister
ValidatorsList.Remove(AddressOf MyClassValidator)
End Sub
Public Function MyClassValidator(ByRef ThisLine As ReadData) As ValidationResult
...
End Function
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free other state (managed objects).
UnRegister()
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
End Module
Scott.Macmaster
January 2nd, 2009, 05:07 PM
Ok, I have a better idea of what your trying to do. However, it still seems wierd that you can have multiple objects that can process the same data.
I don't see the point of using delegates. They're generally used in response to handling events. When loading data you should directly call functions to validate the input. delegates would created unneeded overhead.
I think I may of misunderstood what you had said earlier. I thought you wanted to use reflection to find each instance of certains classes. However, I realize now that you probably wanted to use reflection to find every class that can process your data. If you put all your classes in a module then you can use reflection to search for these objects.
Looks like you made a couple posts while I was typing up a code example. However, it still looks like my example will help.
It looks for all objects in a module that has certain methods. In my example, I have a shared method that is used to determine is the class can process the data or not. interfaces can't define shared methods so I had to check to see if the method was a member. If you need instance members you can make that part of a interface and simply check if the class implements the interface. I didn't check the properties or the return type of the shared method. I thought I let that be an exercise for you.
Well, he's my code example,
Module Module2
Public Class Data
Public Processors As New List(Of Processor)
Public Sub LoadDataFile(ByVal filePath As String)
Dim type As Type = GetType(ProcessingObjects)
' Verify all objects in 'Module ProcessingObjects' have what they need
Dim memberInfo As MemberInfo() = type.GetNestedTypes()
For i As Integer = 0 To memberInfo.Count - 1
Dim currentType As Type = type.GetType(memberInfo(i).ToString())
Dim baseType As Type = currentType.BaseType
If baseType.Name() <> "Processor" Then
Throw New Exception("Error: " + currentType.Name() + " does not inherit from Processor")
End If
Dim method As MemberInfo = currentType.GetMethod("CanProcessLine")
If method Is Nothing Then
Throw New Exception("Error: " + currentType.Name() + " does not have CanProcessLine")
End If
Next
' Load each line of data file.
' For each line for every class that can process that line and add it to the list of processors
Dim lines As String() = File.ReadAllLines(filePath)
For i As Integer = 0 To lines.Count - 1
For j As Integer = 0 To memberInfo.Count - 1
Dim currentType As Type = type.GetType(memberInfo(j).ToString())
' Call the shared member "CanProcessLine" to see if the class can
Dim args() As String = {lines(i)}
Dim useIt As Boolean = CBool(currentType.InvokeMember("CanProcessLine", BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.Static Or BindingFlags.InvokeMethod, Nothing, Nothing, args))
If useIt Then
' if so, create an instance and add to list
Dim processor As Processor = CType(Activator.CreateInstance(currentType, args), Module2.Processor)
Processors.Add(processor)
End If
Next
Next
End Sub
End Class
Public MustInherit Class Processor
Protected Data As String
Public Sub New(ByVal info As String)
Data = info
End Sub
End Class
End Module
Module ProcessingObjects
Public Class DataType1
Inherits Processor
Public Sub New(ByVal data As String)
MyBase.New(data)
End Sub
Public Shared Function CanProcessLine(ByVal line As String) As Boolean
If line.StartsWith("1") Then
Return True
End If
Return False
End Function
End Class
Public Class DataType2
Inherits Processor
Public Sub New(ByVal data As String)
MyBase.New(data)
End Sub
Public Shared Function CanProcessLine(ByVal line As String) As Boolean
If line.StartsWith("2") Then
Return True
End If
Return False
End Function
End Class
End Module
Marraco
January 5th, 2009, 03:11 PM
Ok, I have a better idea of what your trying to do. However, it still seems weird that you can have multiple objects that can process the same data.
I don't see the point of using delegates. Well, in fact, first, I where thinking on send the entire object reference (instead of delegates), but that way, I was forced to expose some private instances, only to expose a single routine. By the way, I could not pass Me as parameter, so I thinked on passing a pointer to the instance function. That lead me to delegates. After it, I read that a new version of VB.NET (2008?) allows a specific "Function" type. Probably it is a better solution. Not investigated.
As I see, a delegate purpose is to encapsulate a pointer to a function.
They're generally used in response to handling events. When loading data you should directly call functions to validate the input. delegates would created unneeded overhead.Although is more complex than this, for example, a line can contain the path of a file. Then, I have objects whose responsibility is to manage files, so I want those objects to check if the path is valid, and if not, mark them as unknown path. I don't want other classes messing with files. I have only one module managing all files, and it should not allow any other to touch them.
But then, I have some classes which need a given set of files. For example, any file with extension ".RST" should have also a file ".RDC", and both files need to satisfy a given data structure. That is a specific requirement, who need to be coded on the class who needs it. I can't move his code to other place, otherwise, I can loose track on who is related to that piece of code.
Anyway, I cannot let a third class to open files to check them. The third class, then defines a regular expression, for each kind of file, and is the file manager class who open the file, check it with the regular expression, and closes it.
... and that file path, is related to a given point on a map. Then another class, who manages points on maps, need to identify that point, and check than the line makes sense from his own viewpoint. ¿the location exists? ¿The text is misspelled? ¿a new instance of PointsOnTheMap class need to be created, or this data need to be added on an existing instance?
... and there exists already i7 processors whit 8 virtual cores. (Saddly, I still have not one (:( )), So, in the future, I want all those tasks to be capable of run in parallel.
isolating each checking and data processing code, on his own class, requires to define the way each class should behave. Do it class need to access files? Not so easy. It need to agree to a standard, who the file manager rules. A way to force them to adhere to the standard, is to define an interface, so when I need to write the code to access that file, I need to implement the interface. It forces me to no forget to code something, otherwise the compilator rant and whine until I fix the bugs.
¿is there a better way? No idea.I think I may of misunderstood what you had said earlier. I thought you wanted to use reflection to find each instance of certains classes. However, I realize now that you probably wanted to use reflection to find every class that can process your data. If you put all your classes in a module then you can use reflection to search for these objects.I don't care if is about Reflection. It only need to do the job, and in a reliable way.
For example, this station contains rain data? I should ask his class if it contains rain data, and then what to do. ¿contains temperature data? Is not my business to decide if it contains temperature data, I should call a class managing temperature.
¿What if tomorrow, some stations add a wild guinea pig counting? I want to write a class named GuineaPigClass. I don't want to recode other code out of the new GuineaPigClass. At startup time, my old code automatically would search for a new class implementing the interface, use it to ask the new class if a given place have anything to do with guinea pig, and if true, then run the guinea pig code.
I don't know how many new classes I can write in the future, which a given interface, or how many instances would do different things.
What new data I gonna read from the file in the future? Don't know. How to validate that data? don't know. But if it contains a file path, I don't want to write again code I already have. The file path would be automatically checked.
And If Nobody checked a given line, then some bug is present, Probably some coding work was left in the task list.
---------------
...
Well, he's my code example,
Module Module2...
It anyway need to know what module contains a class implementing the interface.
I tried to seam it whit this another code, who founds any class implementing the interface:
(Note: If somebody finds this web page with Google probably want this code, because I asked Is there a way to find all classes ... which implement a given Interface?)
Dim asm As Reflection.Assembly = Reflection.Assembly.Load("MyAssemblyName")
Dim types As Type() = asm.GetTypes()
Dim Implementators As Object = types.Where(Function(x) x.GetInterface("IMyInterface") IsNot Nothing)I like this other a bit more (taken from here (http://stackoverflow.com/questions/26733/getting-all-types-that-implement-an-interface-with-c-35)):
Dim type As Type = GetType(IMyInterface)
Dim Implementators As IEnumerator = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(Function(f) f.GetTypes()).Where(Function(g) type.IsAssignableFrom(g))It returns the list of classes which implements a given interface, although I have done nothing useful with it, because, although it accept being declared as Object, or Ienumerable, they don't are cast to that types. Also cannot be cast as array of Type.
I cannot even tell what type is contained in "Implementators" variable. GetType returns a mess, or crashes.
-----------
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.