Chaos Project

General => Electronic and Computer Section => Programming / Scripting / Web => Topic started by: stripe103 on August 20, 2012, 02:45:43 pm

Title: [C#] Changing parent variable without constructor
Post by: stripe103 on August 20, 2012, 02:45:43 pm
Okay, so I've been trying this all afternoon, but can't make it work properly.
I'm making a basic kinda of event-system for our Unity3D project, and I'm having trouble.

Basically, I want to have two(for now) strings in every class that derives from the class EventCommand.
Those variables are then going to be read by the Unity editor script by using something like

foreach (EventCommand cmd in eventCommands) {
  if (cmd.CommandName != null) {
    eventBase.tabs[selectedTab].commands.Add(cmd);
  }
}


that will then add the command to a list of commands.

Problem is that I can't get it to read anything more than an empty string, or whatever is set in the EventCommand class.
So I want to be able to change those two variables (or functions, if that's better) into returning custom strings for each class that inherits from it.

I've tried using functions (both normal like the ones below, as well as using virtual or abstract and overriding them)

Code: EventCommand.cs

public class EventCommand {
  // Preview of command configuration
  public string CommandString() {
    return "";
  }

  // Name shown in list of commands
  public string CommandName() {
    return "";
  }
}


Code: EventMessage.cs

public class EventMessage : EventCommand {
  public new string CommandString() {
    return "Show Message: Text here";
  }

  public new string CommandName() {
    return "Show Message";
  }
}


And I've tried using normal variables (as below, as well as using const, basically, I've tried everything I can think of.)

Code: EventCommand.cs

public class EventCommand {
  // Preview of command configuration
  public string CommandString = "";

  // Name shown in list of commands
  public string CommandName = "";
}


Code: EventMessage.cs

public class EventMessage : EventCommand {
  public new string CommandString = "Show Message: Text here";
  public new string CommandName = "Show Message";
}


Am I just stupid, missing something, or is there a better way to do this?
If someone experienced could help me with this, as it's a school project that's pretty important, I'd be very grateful.
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 20, 2012, 03:04:56 pm
Make a property and set it as virtual.

public virtual string CommandString {get; set; }


Now derived classes can inherit the property.
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 20, 2012, 04:26:09 pm
Hmm... simple as that, eh..
I guess I should start using properties more often..
I'll test it out tomorrow.

But why wouldn't it work with the methods that I made? Why didn't the other classes override at all?
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 20, 2012, 04:28:27 pm
You have to specify methods that override, otherwise they use the parent class method.

In Parent:
public virtual void DoSomething() {}


In Child:
public override void DoSomething() {}
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 20, 2012, 04:36:37 pm
That's what I did though, and then I tried getting it with ParentClass class = new ChildClass(); class.DoSomething();
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 20, 2012, 05:32:22 pm
Why would you do this? :
ParentClass class = new ChildClass(); class.DoSomething();


If the class is derived from the parent, and the method is set to "virtual", as long as you don't override the method, it IS calling the parent's method. I don't understand what you are you are trying to do by creating an instance of ParentClass by instantizing and casting a ChildClass. In the example you gave above, "class" is an instance of a ParentClass, not a ChildClass. It is uses and implicit cast, and won't throw an error since the constructor is a derived class.

Think of this example:
using (Stream str = File.OpenRead("somefilename.dat")) { <CODE HERE> }


"File.OpenRead" returns a FileStream object, not a Stream object, but in the example, "str" is an instance of a Stream, not a FileStream. Basically it becomes whatever the declaration is on the left, not the constructor on the right.
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 21, 2012, 01:06:10 am
Reason why I do it is because then I can store any childclasses in the ParentClass variable. Like I do in the game items for example:
Item item = new Apple();
return item.Name;  // Returns 'Apple'
item = new Potion;
return item.Name;  // Returns 'Potion'


This way, it's easier for me to loop through all Item() in for example my inventory and then get the name of each one, even though they are all different subclasses(or whatever it's called) and show on the screen.
Or I can call the Use method of the chosen item.

It probably isn't the best way to do it, even using Interfacea would probably be easier(learned about them only three days ago), but it works, and having only programmed C# in about a year, I'm pretty proud of the result so far. And as I learn more, I will most likely go back and redo things I can do better.
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 21, 2012, 08:18:08 am
Yeah, an Interface would be the way to go with that. That's pretty much what they are used for. Just create an interface, make empty declarations within it, have your classes derive from it, and implement the methods within it. You will then be able to loop through them just as you need.
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 21, 2012, 09:11:31 am
I think I'll keep the classes until I've learned how to work with interfaces, because I just tried, and it didn't work as easy right now, but I'll keep it in mind later.

Thank you for reminding me of properties though, it worked perfectly.
Title: Re: [C#] Changing parent variable without constructor
Post by: G_G on August 21, 2012, 09:52:52 am
Interfaces are just as easy as making classes.

interface Item
{
   public string Name { get; set; }
   void OnUse();
}

class Apple : Item
{
   public Apple()
   {
       Name = "Apple";
   }

   public void OnUse()
   {
       Console.WriteLine("Apple OnUse");
   }
}

Item apple = new Apple();
Console.WriteLine(apple.Name);
apple.OnUse();
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 21, 2012, 11:12:28 am
Yeh, I guess I'll have to change that later when I have time. It's just that sometimes I want to have a method in the parent class to run after it's override method in the child class have been. Can you do that with interfaces? Just do like

public override void Something() {
  // Do thingiez
  base.Something();
}
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 21, 2012, 11:29:03 am
If the child class derived from the parent. Interfaces do not implement any actual logic, they just declare properties/methods. They are handy because C# does not support multiple-inheritance of classes, but you can inherit from as many interfaces as you like.

They basically just create a common link saying: "this class will contain these properties/methods".
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 21, 2012, 12:11:49 pm
...sooo, you can't. Then I can't use interfaces all the time, but I will use them most of the times though :)
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 21, 2012, 12:22:29 pm
I don't understand what your last post meant. I think you may have misunderstood what I said.
Title: Re: [C#] Changing parent variable without constructor
Post by: Blizzard on August 21, 2012, 12:52:55 pm
This is where you use a class or abstract class instead of an interface.
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 21, 2012, 01:10:34 pm
There is no "base" when deriving from an interface. I'm guessing you want the base class to have fuctionality, so that "base.DoSomething()" does something. If that's the case, then an abstract class is not the way to go.
Title: Re: [C#] Changing parent variable without constructor
Post by: Blizzard on August 21, 2012, 02:21:21 pm
An abstract class is only used if you have data but still need abstract methods. Obviously this class can have other methods which may or may not be abstract, that's what I was trying to say.
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 21, 2012, 03:17:28 pm
Quote from: ForeverZer0 on August 21, 2012, 12:22:29 pm
I don't understand what your last post meant. I think you may have misunderstood what I said.


This is what I understood:

Can you do that with interfaces? Just do like...
If the child class derived from the parent. (Which I automaticly added ", yeah" after it.)
Interfaces do not implement any actual logic (Meaning you can't do what I asked)

So yeah, one of us misunderstood the other.
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 23, 2012, 06:44:42 am
Okay, so I've run into another problem. It turns out that, to be able for Unity to save the values in each scene(which I need),
it is neccessary that it is variables, not properties.
I tried using interfaces, but they can't do variables, and when trying with an abstract class, I don't seem to be able to override
variables, so that doesn't work either.

So, somehow, I need a base class/interface/whatever where I can declare:

public string Name; // Name of the command, this will not change from the value set by each child class.
// Since the Name won't change, I guess it would work with a property that just get's a set string, but it's just so
// you know.

public string CommandString; // Used to get a preview of the command configuration
public Color CommandColor; // The color shown in the editor
public Transform thisTransform; // A reference for the command to be able to get it's own gameObject
public bool IsDone; // If true, goes to the next event command

// Run when scene is started
public void Start();
// Run once every frame, if the command is active.
public void Update();
// Run when needed. Might be multiple times per frame, if the command is active
public void OnGUI();
// Run when editor window is updated
public void DrawEditor();


These will then be needed to be accessed from each child class.

Anyone know a simple solution to this?

PS: Sorry if I'm a bit of a pain, but this is the easiest way for me to learn without needing to take a class in it.
Title: Re: [C#] Changing parent variable without constructor
Post by: ForeverZer0 on August 23, 2012, 09:07:42 am
Have the get/set og the properties change the values of the fields.
Its against C# convention to have fields accessed directly from outside the class. You should use a property to set them if you need to use them from outside.
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 23, 2012, 10:13:15 am
Yeh, I know you should use properties, but with Unity, public variables is just as easily accessed, so you might as well use them instead, but I'll try.

Edit:
Oh wait... when using System.Activator.CreateInstance, is the constructor triggered? If so then this whole conversation was unnessecary :)
Title: Re: [C#] Changing parent variable without constructor
Post by: stripe103 on August 28, 2012, 07:59:35 am
DOUBLE POSSSSSSSTTTTTTT!!!!

Once again, I need help with the system I'm currently trying to get to work..
For the last problem, I managed to fix it using virtual methods(which I tried before too, but couldn't get to work),
now there is just one thing left to fix.

Because I use child classes for each Event Command, it doesn't load the correct class,
and loads the information into EventCommand instead of EventMessage in this case, so it uses
those methods instead.

I have a simple way of saving the class type ID, that I use for listing all commands. I just need some simple way to use the
methods in the child classes instead of using the EventCommand ones, that doesn't do anything.

I thought of doing something like this
(eventCommands[cmd.classTypeID].GetType())cmd.Update()

or
cmd.Update() as eventCommands[cmd.classTypeID].GetType()

Of course, none of those worked, it was just what I came up with that maybe could work..
So basically, the command in cmd is of type EventCommand, but I want it to get the type "eventCommands[cmd.classTypeID].GetType()"
and use that to run the right class method.