Instantiate many classes - vb.net

In my current project, a circuit drawing program, I'm deriving many classes from the same base class.
Public MustInherit Class clsCompo
Public Class clsRelay Inherits clsCompo
Public Class clsResistor Inherits clsCompo
Each child class has a 'getIcon' function that provides the desired image of the component. These get loaded in a listview to be used in the drawing program.
Is there an easy way to instantiated these classes to be used? Is there another way than manually instantiating each class? And then adding the image to the listview: something like:
Dim classes() As String = {"clsResistor", "clsRelay"}
Dim c(1) As Object
For Each cls As String In classes
c(1) = New cls
'add image to listview
Next
I'm using .NET 3.5
Thanks

If your classes have a parameterless constructor:
c(1) = Activator.CreateInstance(Type.GetType("MyNamespace." & cls))
Obviously, MyNamespace. should be replaced as appropriate.

You will need to use reflection and Activator.CreateInstance specifically to perform this trick. Going towards reflection path is dangerous, and usually brings more trouble than it gives benefits. In most cases there is a better way to design your application.
In your particular case, you could have a dictionary of icons, string to icon match, then just have a constructor of clsCompo specify the icon you want as a parameter. Unless you are using inheritance for something else, this should totally solve your problem, without the burden of using reflection.

Related

How does VB.NET execute a non-shared method without an instance? [duplicate]

I'm just curious to know that there is the (Name) property, which represents the name of the Form class. This property is used within the namespace to uniquely identify the class that the Form is an instance of and, in the case of Visual Basic, is used to access the default instance of the form.
Now where this Default Instance come from, why can't C# have a equivalent method to this.
Also for example to show a form in C# we do something like this:
// Only method
Form1 frm = new Form1();
frm.Show();
But in VB.Net we have both ways to do it:
' First common method
Form1.Show()
' Second method
Dim frm As New Form1()
frm.Show()
My question comes from this first method. What is this Form1, is it an instance of Form1 or the Form1 class itself? Now as I mentioned above the Form name is the Default instance in VB.Net. But we also know that Form1 is a class defined in Designer so how can the names be same for both the Instance and class name?
If Form1 is a class then there is no (Static\Shared) method named Show().
So where does this method come from?
What difference they have in the generated IL?
And finally why can't C# have an equivalent of this?
This was added back to the language in the version of VB.NET that came with VS2005. By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type. Form1 vs frm in your snippet. There's history for that, VB didn't get classes until VB4 while forms go all the way back to VB1. This is otherwise quite crippling to the programmer's mind, understanding that difference is very important to get a shot at writing effective object oriented code. A big part of the reason that C# doesn't have this.
You can get this back in C# as well, albeit that it won't be quite so clean because C# doesn't allow adding properties and methods to the global namespace like VB.NET does. You can add a bit of glue to your form code, like this:
public partial class Form2 : Form {
[ThreadStatic] private static Form2 instance;
public Form2() {
InitializeComponent();
instance = this;
}
public static Form2 Instance {
get {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
}
return instance;
}
}
}
You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET. The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.
Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair. A problem when the abstraction is leaky. You are really better off not doing this at all.
VB is adding a load of code into your project behind your back, basically.
The easiest way to see what's going on is to build a minimal project and look at it with Reflector. I've just created a new WinForms app with VB and added this class:
Public Class OtherClass
Public Sub Foo()
Form1.Show()
End Sub
End Class
The compiled code for Foo looks like this when decompiled as C#:
public void Foo()
{
MyProject.Forms.Form1.Show();
}
MyProject.Forms is a property in the generated MyProject class, of type MyForms. When you start diving into this you see quite large amounts of generated code in there.
C# could do all of this, of course - but it doesn't typically have a history of doing quite as much behind your back. It builds extra methods and types for things like anonymous types, iterator blocks, lambda expressions etc - but not in quite the same way that VB does here. All the code that C# builds corresponds to source code that you've written - just cleverly transformed.
There are arguments for both approaches, of course. Personally I prefer the C# approach, but that's probably no surprise. I don't see why there should be a way of accessing an instance of a form as if it was a singleton but only for forms... I like the language to work the same way whether I'm using GUI classes or anything else, basically.

RealProxy issues with compile time

I have a class MyProxy derived from RealProxy and implemented the bare minimum of Invoke to silence compile time errors. I inherit from MyProxy a custom class TabControl2 which itself wraps (ie: decorator) an TabControl.
I wish to call/intercept TabControl methods via the decorator - implementing everything myself as a learning exercize.
I understood the Invoke() of RealProxy would allow runtime interception of undefined methods in the decorator and call Invoke() with details of the invocation, such as method and arguments; thus allowing me to optionally invoke the original "decorated" object
I have googled for examples found many in C# and ported much of the code over to vb.
This particular bit of code is killing me:
Dim tabCtrlGeneric As TabControl = New TabControl()
Dim tabCtrlDecorator As TabControl = CType(New TabControlReorder(tabCtrlGeneric), TabControl)
Is giving me a compile time errors about type...not sure why?

Why does adding 2nd level subclassed Button controls to a Grid give E_INVALIDARG?

I've come across the this problem dealing with subclasses of the Windows.UI.Xaml.Button class in C++/CX, and I'd like to know what's going on.
If I add a control instance to a grid, everything works as expected.
If I subclass the control and add an instance of the subclass, everything works as expected.
But if I subclass my subclassed control and add an instance of it to the grid I get E_INVALIDARG thrown during Grid::Children::Append(). What gives?
My code looks roughly like this (LayoutRoot is a Grid in MainPage.xaml, this sample has been tested in an empty simple metro application):
// Scenario 1: This works (duh!)
LayoutRoot->Children->Append(ref new Button());
// Scenario 2: This works
LayoutRoot->Children->Append(ref new MyButton1());
// Scenario 3: This doesn't work, it will cause an E_INVALIDARG to be thrown by the collection
LayoutRoot->Children->Append(ref new MyButton2());
// This is how MyButton1 and MyButton2 is defined
public ref class MyButton1 : public Button {
public:
MyButton1() {};
~MyButton1() {};
};
public ref class MyButton2 : public MyButton1 {
public:
MyButton2() {};
~MyButton2() {};
};
Note that this question is slightly similar to this question, but the error and the scenario is sufficiently different for me to post this one separately.
UPDATE: I think I'm on the right track understanding this problem after reading this article by Ian Griffiths, but I need to know more regarding the behavior of this specific example. Full code to repeat this problem can be found here, see the 3rd post in the thread.
UPDATE: From what I've learned so far, not all WinRT types support inheritance. I have no reliable source references for this, but I've read that the Windows.UI.Xaml classes should support inheritance, but other WinRT types won't. The Windows.UI.Xaml.Controls.Button class obviously does, while my own MyButton1 doesn't. I'd like to know what I'd have to do to make MyButton1 'inheritable' the way the Button class is.
I've found that replacing the Windows.UI.Xaml.Controls.Button class with Windows.UI.Xaml.Controls.ProgressBar will make scenario 2 fail, which tells me that the ProgressBar class isn't (yet) possible to subclass. This observation is what makes me believe that a class need to do something explicit in order for it to be inheritable.

is it possible to extend activity class and PreferenceActivity class at the same time

I want to have my main class for creating activity for 2 different flags.
1) One with relative layout Textview and images for which I am extending my class as
public class Abcd extends Activity implements View.OnClickListener, _
AdapterView.OnItemClickListener, ViewFactory{
2) secondly with linear layout as to have a textview imageview and list.
now for the second case I want to use preferencescreen instead of list, for which I have to extend my activity from PreferenceActivity .
Need your suggestion if I can do so.
Thanks
Vani
VB does not support it, neither does C#.
This is referred to as Polymorphism and there's plenty of information available if you search for that word.
Generally you would want polymorphism because you want to attach two types of behavior to the class - you can achieve this just as easily by using composition over inheritance - again there is plenty of advice available if you search for that term.

Why Can't I Inherit IO.Directory?

Why can't I create a class in VB.NET that inherits System.IO.Directory? According to Lutz Roeder, it is not declared as NotInheritable!
I want to create a utility class that adds functionality to the Directory class. For instance, I want to add a Directory.Move function.
Please advise and I will send you a six pack. OK nevermind I'm not sending you anything but if you come to the bar tonight I will hook you up and then beat you in pool.
From the Meta Data of .NET
namespace System.IO
{
// Summary:
// Exposes static methods for creating, moving, and enumerating through directories
// and subdirectories. This class cannot be inherited.
[ComVisible(true)]
public static class Directory
You cannot inherit from a Static Class.
Are you using C# 3.0 VB.NET 2008 -- then you could add an Extension Method
If you use the DirectoryInfo class, you will have access to a MoveTo function.
EDIT: I'll correct myself... The static Directory class already has a Move method.
I'd guess that Reflector isn't picking up the sealed attribute correctly for VB (or perhaps just not displaying it properly). If you look at the IL, it is sealed:
class public abstract auto ansi sealed beforefieldinit Directory