|
Hi jrahma,
I cannot compile this code for obvious reasons coz there are so many links in it.
Can't you strip down this code to bare minimum and see just post the problem area? Basically public_class with minimum requirements and two basic forms with calling public_class?
if the problem doesn't happen in that form, it is not a problem related to hashtable.
Som
|
|
|
|
|
as I have mentioned in my MSDN thread, I have no problme compiling the code because no errors dring the build. The error pops up a run time. I als don't have problem when moving the line:
MessageBox.Show(public_var._sysem_parameters_hash("Name").ToString());
to main_form.cs
|
|
|
|
|
What I understood from the complete QA is that you face an error when you access a member of hashtable.
I cannot go through each line of your code to identify where the problem happens till the time i cannot compile the complete code. If you can provide a stripped down version of three cs files which i can compile and find the error during run time, i could help.
You could otherwise try to add a breakpoint just before the line where error happens and look into contents of hashtable. may be you can write a method to do just this.
The following method will show the contents of the hashtable in the output window. When you see the error in the messagebox line, u can see if the content is available in the hashtable or not.
private void PostDataIntoDebug(Hashtable _sysem_parameters_hash)
{
#if DEBUG
foreach (var a in _sysem_parameters_hash.Keys)
{
Debug.WriteLine(string.Format("{0} - {1}", a, _sysem_parameters_hash[a]));
}
#endif
}
|
|
|
|
|
I am getting:
Object reference not set to an instance of an object.
on this line:
foreach (var a in public_var._sysem_parameters_hash.Keys)
from your code...
you might say because hashtable is not initilized or somkething similar.. but why? that's my question...
Thanks...
|
|
|
|
|
jrahma wrote: you might say because hashtable is not initilized or somkething similar.. but why? that's my question...
Well, this is the answer not the question. You need to go through your code step by step and find out where the hashtable was initialized.
I went through the complete discussion once again on MSDN. What i understand is that you are utilizing the same hashtable from different forms but you are initializing them separately.
I suggest making a small change of making the class and variable static and see if this solves your purpose:
static class public_class
{
public static Hashtable _sysem_parameters_hash;
public static void get_system_parameters()
{
_sysem_parameters_hash = new Hashtable();
_sysem_parameters_hash.Add("Name", "Jassim Rahma");
}
}
|
|
|
|
|
Now I cleaned the whole application an created a new application just for the hashtable issue and I am still getting the same error.
Hashtable project
The above file has a hastable project with three files.. public_class.cs, Form1.cs and Form2.cs, you can see that no issue reading the value in Form1 load but when you click on Form2 it will throw the error... it's seems the hashtable was no initilized but i don't know what to do to fix this in Form2...
modified on Monday, April 26, 2010 9:54 AM
|
|
|
|
|
Well it was easy to catch. Thanks for the effort of stripping it down.
Just change
Form2 myForm = new Form2();
to
Form2 myForm = new Form2(public_var);
and it works. You created the Constructor but didn't use it.
|
|
|
|
|
Problem solved
Thanks Som....
Thanks everyone...
|
|
|
|
|
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());
}
}
|
|
|
|