|
and I have also written something to what you want to write:
http://www.adersoftware.net/?page=oyster
You can download it for free, and if you want to look at the source code, let me know and I can send it to you.
|
|
|
|
|
Hi all,
i would like to set up a logic like this:
A Collection class School which holds different class-members like:
* student
* teacher
* table
* chair
* classroom
* stairs
Member classes have different values (and methods), like:
- student has: name, age and classroom <small>(link to classroom id?)</small>
- teacher has: name
- table has: pointF position, color and tabletype <small>(an enum)</small>- classroom has: pointF[] polyline, ID, classroomtype and MaxPersons
- stairs has: pointF startpoint and pointF startpoint
I would like to get information for all elements in the main class collection using the foreach statement.
Then using it's type i can act on it. For a classroom i could show the position PointF[] on an image and for the students i could show only the students which are in that particular classroom.
Pseudo code:
Foreach element in MainSchoolCollection
If element.type is typeClassroom
PointF[] thePoints = element.vertices[]
element.DrawMyClassroom(thePoints)
int ClassID = element.ID
Foreach element in MainSchoolCollection
If element.type is typeStudent
MessageBox.Show(element.name)
EndIf
EndForeach
EndIf
If element.type is typeStairs
element.StairsToLine(element.startpoint, element.endpoint)
EndIf
EndForeach
So the main issue is that each element in the collectionclass has different properties and methods. When looping through the main collection i would like to use/modify the element's property based on it's type.
Can anyone point me in the right direction here?
Thanks,
Me.
|
|
|
|
|
first, you have to define element and give it a common description, i.e., something that goes for all items. Then, you can implement the IEnumerable interface in all items, so you can use an enumerator.
You might even use an emty interface, which can be used as element in the foreach loop, and then cast the element to the containing type, just as you did.
|
|
|
|
|
Hoi Rakker,
klink Nederlands,... )
Do you happen to know if this subject is explained in a tutorial somewhere,... i'm relative new to interfaces.
Thanks.
|
|
|
|
|
This is one thing that object-oriented programming solves. Define an abstract base class with all the properties and methods that are shared by every derivative class. Some of these properties may even be abstract themselves, declaring that derivative class must override them (perhaps to provide a friendly name of the object, rather than just returning the class name).
A simple hierarchy of classes I see from your list is like so:
abstract SchoolObject
+abstract Person
|+Student
|+Teacher
+abstract Item
|+Table
|+Chair
|+Classroom
|+Staircase So the abstract SchoolObject would define the properties you need for everything. Your SchoolCollection accepts types of SchoolObject s, which can be an instance of any derivative class. As you're enumerating your collection, you can access the shared properties of SchoolObject , which - if virtual - the derivative classes can override to return different results.
This is really a core concept of object-oriented programming. If you're new to object-oriented programming or programming in general, I recommend you pick up a good book or two on object-oriented programming with .NET, such as Learn to Program with C#[^] (top-rating from a quick Amazon.com search). Object-oriented programming is also taught in most college curriculums, and can be picked pretty easily by reading through the documentation and looking at examples (CodeProject has thousands of examples).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi Heath,
thanks for the reply and info.
Comming from a VB background and using collection classes there i thought things would be similar, but i could not get the properties of the elements in my collection.
In VB i used like:
collection class:
Private mCol As Collection
Public Function AddClassRoom(ByVal Name As String, ByVal MyCenter As Coord) As ClassRoom
Public Function AddStudent(ByVal FirstName As String, ByVal Lastname As String) As Student
Both Student and ClassRoom are seperate classes with different properties and methods.
Problem is that there seems no simple translating to the Private mCol As Collection part.
Reading to do for me,...
Thanks again.
|
|
|
|
|
If you really want arbitrary objects to be in your collection you could simply use the base collection classes from System.Collections.
They usually have object derived items, so you can stuff in what you like.
When you're enumerating these collections you can determine the type of each item by something similar to (in C#):
ArrayList myCollection = new ArrayList();
[...].
foreach (object o in myCollection)
{
if (o is Teacher)
{
Teacher t = o as Teacher;
t.DoSomethingOnlyTeachersDo();
}
if (o is Chair)
{
Chair c = o as Chair;
c.StandThere();
}
}
mav
|
|
|
|
|
Hi Mav,
Thanks, that did the trick !
I have the setup correct in general:
collection class with elements called obj which is an interface and all objects i store in the collection 'derive' from obj.
So, using class objects like:
public class objTeacher : obj
public class objStudent : obj
My problem (major error ) was that i did not 'copy' the properties of a 'general' object to the object i need like your example:
if (o is Teacher)
{
Teacher t = o as Teacher;
string test = t.TeacherName;
t.DoSomethingOnlyTeachersDo();
}
in my case i could not access the propertie TeacherName because it is an object/class specific property.
Casting it as a Teacher object did the trick !
How live can be sweet and simple sometimes
So to understand the logic here, the Teacher is a derivate of the obj interface.
Is this the propper structure to enumerate and use different objects in 1 collection, or am i on a dangerous path here?
Me.
|
|
|
|
|
I think it's the easiest way to go.
In fact you wouldn't even have to derive from obj , because all classes in .NET implicitely inherit object , which is the item type of most base collections.
Using an obj interface might be the cleaner way if you want to ensure type safety at compile time. But then you have to make the collections typesafe (for example by deriving from CollectionBase and overriding the required methods). And find a meaningful interface.
I usually doubt if an empty marker-interface/base class (I think somebody suggested this) is a good idea from an object oriented view. By defining an interface you extract all common properties and behaviour into the interface, but if you can't find anything the different classes implementing your interface have in common then why should you create an interface?
One caveat remains, though. Using object derived items will allow you to add anything to your collection at compile time, even if this might not be desireable. You will not be able to check this until run time.
Regards,
Mav
|
|
|
|
|
I now removed the interface and use object to enumerate,... works perfectly.
Thanks !
|
|
|
|
|
Despite what Microsoft marketing tries to tell you, VB6 is nothing like VB.NET (which is just a language which targets the CLR and uses a common class library). Collections are objects all by their lonesome and you can extend CollectionBase if you want to avoid a lot of the mess but still provide typed parameters (you could override Add , for example, and provide a parameter type as the base class).
You'll still want to go with an abstract object model as everyone here so far has told you. This is something VB couldn't do and is very powerful and leads to clearner designs than prototyping functions like you did in your snippet (having one method to add the base class defined on the collection itself).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks Heath and Mav,
yes VB is a whole different cookie to eat then C#,...noticed )
Will do some reading/investigating regarding the abstract model or go for the mav-version [ArrayList-logic].
Base, Abstract, Virtual, Interface and Derivative classes.
A class collection with a collection of 1 class i got covered.
Mostly i work of examples / snippets but did not find anything regarding various calsses in one collection.
So, welcoming myself to the new world )
|
|
|
|
|
Mav's way, IIRC, uses interfaces. Interfaces and abstract classes differ mostly in the fact that abstract classes can at least contain some functionality. Take the top-most class from which all classes derive: System.Object . It's ToString method is available on any class with default behavior to return the namespace-qualified type name, but classes can override it to return something else. With an interface, each implementing class would have to override it; they don't have a choice. Also, a class can implement multiple interfaces, but can only extend one class.
pxp wrote:
yes VB is a whole different cookie to eat then C#,...noticed
Actually, even VB.NET is different. The syntax is mostly the same, yes, but the output is very different. VB.NET, C#, MC++, and any other managed languages can use assemblies written in any other language because the language compiler for each language compiles to Intermediate Language (IL). Some languages may not support all the features of the Common Language Infrastructure (CLI) and, in many cases, would only be able to use CLS-compliant (Common Language System) types. JScript.NET is a good example.
pxp wrote:
Mostly i work of examples / snippets but did not find anything regarding various calsses in one collection.
Don't think of it as multiple classes but as one class - the abstract class. Sure, in actually the collection contains multiple instances but since each one of those classes derives from the base class (and your collection's methods and properties use that base class).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Various approaches to the same goal, but just what's best shall vary in cases.
The VB logic i brought up was about the same logic. It's collection sonsists of objects. Why did i not know that one can add an object to a collection :P
Thanks for the info.
|
|
|
|
|
I need to create an unknown number of objects, for example DataReaders at runtime. In c# how would I create these names so that the first is dtrFred1 and the next is dtrFred2 etc. Obvisiuosly this will be in the form of a loop. In JScrpit/JavaScript one could use the eval() command, how is this achieved in c#
Robert T Turner
South Gloucestershire Council
|
|
|
|
|
You could hold them in a suitable collection. For instance you can use a Hashtable , where the key is "dtrFred1" etc. and the value is the DataReader.
Does this help?
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
My Blog
|
|
|
|
|
|
Hello!
We are developing a program in c#, we have a problem with probably the threading. After a few minutes running our program, it starts to consume all cpu time, we have not started any own threads.
The running thread does not seem to have any priority, it does not slow down any other programs, it just overrides the idle thread, it seems.
Does anyone know of any known problem using c# concering out problem, or has any other ideas of what the problem might be.
M
|
|
|
|
|
Mikke_x wrote:
After a few minutes running our program, it starts to consume all cpu time, we have not started any own threads.
The running thread does not seem to have any priority, it does not slow down any other programs, it just overrides the idle thread, it seems.
The idle thread is the lowest of the low in terms of priority. Of course your application will override it - it is supposed to do that. The idle thread is just what the OS does when it has nothing else to do. As your application is doing something the OS is therefore not, by definition, idle.
"You can have everything in life you want if you will just help enough other people get what they want." --Zig Ziglar
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
My Blog
|
|
|
|
|
Yeah of course. The problem here was that the process used 99% of the processor all the time. Altough it looked like it had really low priority since it did only use the processor if no other thread wanted to execute.
We did resolve the problem however. Can´t really explain the reason behind the problem, but it was because of a sleeping thread. We started a thread when we started the application and suspended it immedediately. Now we have changed it so that we don´t start the thread until we need it instead of starting it and suspend it from the start.
M
|
|
|
|
|
I have made a Treeview, I add only parents.. no child.. I can do that, but the problem is in counting the no. of parents.. I have declared an array, called child[5,100] , I intend to count the no. of parents and associated children. my code for adding parent
string node1;<br />
node1=Convert.ToString("RuleSet No." + (p+1).ToString()); <br />
if(p>=5)<br />
{<br />
MessageBox.Show("YOU CAN ADD ONLY 5 ROOT NODES!!!"); <br />
}<br />
else<br />
{<br />
if (ruletree.Nodes.Count<=0)<br />
{<br />
p++;<br />
this.ruletree.Nodes.Add(node1);<br />
child[p,0]=p;<br />
}<br />
else<br />
{<br />
<br />
int nop=ruletree.Nodes.Count;<br />
p=nop;<br />
child[p,0]=p;<br />
p++;<br />
this.ruletree.Nodes.Add(node1); <br />
}
the peob. is that it counts the second parent as the third.. and hence..
HELP!
_____________________________________________________
Believe! Every thing has a purpose
|
|
|
|
|
Sorry to bother you people.. I got it ..
just a '--' did the job..
sorry
_____________________________________________________
Believe! Every thing has a purpose
|
|
|
|
|
How do I disable the selection of a particular node in a tree..
Eg. I don't want to add children to nodes already children.. I can show a messege box.. or do a no-op if a child is selected, but can I disable its selection?
_____________________________________________________
Believe! Every thing has a purpose
|
|
|
|
|
You can cancel the selection of a node by handling the TreeView.BeforeSelect event:
treeView1.BeforeSelect +=
new TreeViewCancelEventHandler(treeView1_BeforeSelect);
private void treeView1_BeforeSelect(object sender,
TreeViewCancelEventArgs e)
{
if (e.Node.Nodes.Count > 0) e.Cancel = true;
} If you want to have more control over what people can add, this is where encapsulation comes in. Rather than trying to hack the TreeView to allow/disallow certain operations, host the TreeView in a UserControl or something where you define methods and properties that reflect operations in the TreeView . This way you can easily perform a check before doing something, like how many nodes exist and whether you should add a new one. To implement this kind of behavior on the tree can be quite difficult. This is the reason for encapsulation.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
ok..
I'll try this.. thank you.
_____________________________________________________
Believe! Every thing has a purpose
|
|
|
|
|