|
Cool.
|
|
|
|
|
How do you store a type in a variable?
Let's say I have the following base class, and a couple of derived classes:
public abstract class MyBase
{
public abstract string Test();
}
public class class1: MyBase
{
public override string Test()
{
return "Class1";
}
}
public class class2 : MyBase
{
public override string Test()
{
return "Class2";
}
}
Now, I want to store the "types" of class1 and class2 in an array, so I can instance the classes, something like this:
MyArray[0] TmpClass1 = new MyArray[0];
MyArray[1] TmpClass2 = new MyArray[1];
Obviously this doesn't work. And I've tried using typeof() and System.Type to do this, but end up getting compiler errors no matter what I try.
So how is it done?
|
|
|
|
|
There may be some strange way you can achieve what you want, but isn't there an easier way? I'm not sure exactly what you intend to do but a very common thing to do would be this:
enum ClassType
{
CLASS1,
CLASS2
}
BaseClass MakeClass(ClassType ct)
{
switch(ct)
{
case CLASS1:
return new Class1();
break;
etc.
}
}
My current favourite word is: Smooth!
-SK Genius
|
|
|
|
|
Well basically I want to add all the derived types to an array so I can choose to instance any of them randomly.
This has to do with reflection doesn't it? Sorry I'm still learning c#.
|
|
|
|
|
You could create a Type[] array, stuff the types you want in it, and later use Activator.CreateInstance()
|
|
|
|
|
Luc, that's exactly what I'm trying to do - a type array. Thanks!
Ok so I can create the array now. But I'm having trouble creating an instance:
Type[] TypeArray = new Type[2];
TypeArray[0] = typeof (class1);
TypeArray[1] = typeof (class2);
But the following gives typecast errors:
MyBase tmp = Activator.CreateInstance(TypeArray[0]);
How do I cast it properly?
|
|
|
|
|
It's ok I've got it! Just need to change it to:
MyBase tmp = (MyBase) Activator.CreateInstance(TypeArray[0]);
But is there a way to do this without using CreateInstance?
|
|
|
|
|
jabbawok wrote: is there a way to do this without using CreateInstance?
not really. Either you use the switch approach with a new in each case (you have to provide explicit code for each possible type); or you use reflection withCreateInstance() (which does not need changes when new derived classes get introduced).
|
|
|
|
|
jabbawok wrote: MyBase tmp = (MyBase) Activator.CreateInstance(TypeArray[0]);
I'm stuck again.
How do you use Activator.CreateInstance when the class has a constructor that takes arguements?
|
|
|
|
|
CreateInstance returns an object , so you need a cast; you want the most general one as your receiving variable is also a general type.
MyBase tmp = (MyBase)Activator.CreateInstance(TypeArray[0]);
The object itself will be specialized though, which you could proof by calling a method that is overridden.
tmp.Test();
|
|
|
|
|
What do you mean by specialized, Luc?
I checked it and the proper derived class is instanced with the correct overridden method being called.
|
|
|
|
|
a cat is a specialized mammal, which is a specialized animal.
|
|
|
|
|
Oh ok smarty That's what I want anyway.
|
|
|
|
|
<blockquote class="FQ"><div class="FQA">jabbawok wrote:</div>MyBase tmp = (MyBase) Activator.CreateInstance(TypeArray[0]);</blockquote>
I'm stuck again.
How do you use Activator.CreateInstance when the class has a constructor that takes arguements?
|
|
|
|
|
|
aspdotnetdev wrote: ConstructorInfo.Invoke should do the trick.
Geez, now there's another way to confuse me
I found it could be done using the following. Basically I'm trying to build a tree of random expression nodes. FunctionList is an ArrayList holding the types, and ParentNode is the "owner" of the newly instanced "child":
ImageFunction ChildNode = (ImageFunction) Activator.CreateInstance( (Type)FunctionList[RandNum], new ImageFunction[] {ParentNode} );
But this is getting messy very quickly. I'm trying to duplicate what I once did in Delphi and that's probably why I'm having so much trouble. In Delphi you could do something similar to:
ImageFunction( FunctionList[RandNum] ).Create( ParentNode ); Is there surely no simpler way to do this in c#?
|
|
|
|
|
jabbawok wrote: Is there surely no simpler way to do this in c#?
Create some helper methods:
public void SomeMethod()
{
Animal a = Create<Animal, Dragon>(5);
Dragon d = Create<Dragon>(5);
}
public TReturn Create<TReturn, TSpecific>(params object[] parameters)
{
return (TReturn)Activator.CreateInstance(typeof(TSpecific), parameters);
}
public TReturn Create<TReturn>(params object[] parameters)
{
return (TReturn)Activator.CreateInstance(typeof(TReturn), parameters);
}
public class Animal
{
}
public class Dragon : Animal
{
public Dragon(int height)
{
MessageBox.Show(height.ToString());
}
}
|
|
|
|
|
Also, this third overload will probably be more useful to you, since you are storing types in variables.
public void SomeMethod()
{
Animal a2 = CreateInstance<Animal>(typeof(Dragon), 5);
}
public TReturn CreateInstance<TReturn>(Type t, params object[] parameters)
{
return (TReturn)Activator.CreateInstance(t, parameters);
}
|
|
|
|
|
Hi,
actually my question is simple, but still I couldn't find the answer. I searched everywhere.
In my project I have a webBrowser control. Before the webBrowser control navigates from one page to another, I have to intercept the post data, so I can analyze it. If for example I would be on a page with a form, and I click on the button to submit the form, I would have to get somehow the data the webpage wants to send via POST.
I work on solving this problem for a long time, so any help would be greatly appretiated.
And sory for my bad english, I'm not a native speaker.
|
|
|
|
|
|
thx for the answer, but the WebBrowserNavigatingEventArgs contain everything exept the data that will be posted.
I guess the only way I get the post data is to read the values of the form input elements .
|
|
|
|
|
Imho that's the right approach.
/ravi
|
|
|
|
|
As part of the app I am expanding, the user needs to be able to annotate an image. I am going to link images to individual item, like a car or a house, and allow the user to annotate that image by circling something, or free form drawing on the image with a stylus or mouse (Likely a stylus with a tablet PC)
The link cannot be a straight line, it needs to follow the course of the user's pen.
Can someone point me in the right direction? I have a basic handle on the GDI+ class, but don't quite see how to draw a free form line.
Thank you!
--EA
|
|
|
|
|
I'm not sure if this is what you need, but I have a similar case where I need to build a line as the mouse moves while the left button is pressed.
On a MouseDown event, I set a flag and initialize things. In the MouseMove event I check to see if the flag is set, save points, and redraw a line as the mouse moves. The MouseUp event clears the flag, saves the points and does whatever else is needed.
CQ de W5ALT
Walt Fair, Jr., P. E.
Comport Computing
Specializing in Technical Engineering Software
|
|
|
|
|
As Walt said, your free form line will consist of a series of short straight lines, built while you move the mouse. Expect a MouseMove event for every two to three pixels you move, unless you are moving very rapidly.
|
|
|
|