Start function not being called C# - c#

I get a component like this
GameObject currentAuraObject
IAura currentAura = currentAuraObject.GetComponent<IAura>();
where current aura is
public class AirAura : MonoBehaviour, IAura
{
public ElementalIncreament DamageElementalIncreament { get; set; }
public ElementalIncreament ResistanceElementalIncreament { get; set; }
public ElementalIncreament EnemyElementIncreament { get; set; }
private void Start()
{
DamageElementalIncreament = new ElementalIncreament(ElementalIncreament.ElementalType.Air, 20);
ResistanceElementalIncreament = new ElementalIncreament(ElementalIncreament.ElementalType.Air, 15);
EnemyElementIncreament = new ElementalIncreament(ElementalIncreament.ElementalType.Earth, 35);
}
}
the variable currentAura itself is not null but all the properties are.. I don't understand why the Start function is not being called and initialise the properties properly, how can I fix this ?

To have a function automatically called in your class you need to create a class contructor like below (the function has to be public, have no return type and be the same name as your class):
public AirAura()
{
DamageElementalIncreament = new ElementalIncreament(ElementalIncreament.ElementalType.Air, 20);
ResistanceElementalIncreament = new ElementalIncreament(ElementalIncreament.ElementalType.Air, 15);
EnemyElementIncreament = new ElementalIncreament(ElementalIncreament.ElementalType.Earth, 35);
}

Related

C# constructor that accepts parameter of the same class

I have a custom class
class MyClassA{
public int Width { get; set; }
}
and another custom class B
class MyClassB {
public MyClassA paramClassA;
public int Height { get; set; }
}
Is there a way to have a constructor inside MyClassB which accepts a parameters of type MyClassB and automatically assigns values to the attribute?
Something like this:
class MyClassB{
public MyClassA paramClassA;
public int Height { get; set; }
public MyClassB(MyClassB param){
}
public MyClassB(MyClassB param){
// automatically assign properties of param to the instance it is created
}
}
So I can do this:
var classB = new MyClassB();
classB.Height = 100;
classB.paramClassA = new MyClassA();
classB.paramClassA.Width = 100;
var classB2 = new MyClassB(classB);
Is there a way to do this?
ThereĀ“s no in-built way to do this. Anyway this is the purpose of a copy-constructor and can be achieved by copying all the properties from your existing instance to the current one. However when you have a deep inheritance-chain copying all those members can be non-trivial task which also includes private members.
class MyClassB{
public MyClassA paramClassA;
public int Height { get; set; }
public MyClassB(MyClassB param){
this.Heigth = param.Height;
this.MyClassA = param.MyClassA;
}
}
You could also implement ICloneable:
class MyClassB : ICloneable {
public MyClassA paramClassA;
public int Height { get; set; }
public object Clone(){
return new MyClassB
{
this.Height;
this.MyClassA;
};
}
}
Yes, you can do it manually. Remember about differences between shallow copy and deep copy in C# language:
class MyClassB{
public MyClassA paramClassA;
public int Height { get; set; }
public MyClassB(MyClassB param){
Height = param.Height;
paramClassA = new MyClassA();
if (param.paramClassA != null)
{
paramClassA.Width = param.paramClassA.Width;
}
}
}
I'll recommend Clone method inside MyClassB class:
class MyClassB{
//....
public MyCLassB Clone()
{
var result = new MyClassB
{
Height = Height
};
result.paramClassA = new MyClassA();
if (paramClassA != null)
{
result.paramClassA.Width = paramClassA.Width;
}
}
}
And use it, like below:
var classB = new MyClassB();
classB.Height = 100;
classB.paramClassA = new MyClassA();
classB.paramClassA.Width = 100;
var classB2 = classB.Clone();
You could always create a copy method that would assign the values and return a MyClassB where you assign the values within. If you must do it in a constructor check out the following.
public MyClassB(MyClassB param)
{
Width = param.Width;
// If you want to keep the same reference classA
paramClassA = param.paramClassA;
// if you want the classA to not be the same reference you could always do.
paramClassA = new MyClassA() { Width = param.Width };
}

Why it doesn't maintain reference to the object?

I can't figure out why MessageBox show "false" if nuovo.matrice refers to the same object but not maintain the array reassignment done by the method. Why nuovo.matrice == mat is false if they refers to the same object?
namespace WindowsFormsApplication15
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
class Class1
{
public ClassType[] matrice;
public class ClassType
{
public string a { get; set; }
public int b { get; set; }
}
}
Class1.ClassType[] mat;
private void Form1_Load(object sender, EventArgs e)
{
Class1 test = new Class1();
Class1.ClassType prova = new Class1.ClassType();
test.matrice = new Class1.ClassType[1];
test.matrice[0] = prova;
mat = test.matrice;
mat[0].a = "rtuier";
mat[0].b = 94;
Modify nuovo = new Modify(mat);
nuovo.inizia();
MessageBox.Show((nuovo.matrice == mat).ToString());
}
class Modify
{
public Class1.ClassType[] matrice;
public Modify(Class1.ClassType[] mat)
{
matrice = mat;
}
public void inizia()
{
matrice[0].a = "asuidh";
matrice[0].b = 123;
Class1.ClassType[] newMatrice = new Class1.ClassType[2];
Class1.ClassType ins = new Class1.ClassType { a = "pollo", b = 456 };
newMatrice[0] = matrice[0];
newMatrice[1] = ins;
matrice = newMatrice;
}
}
}
}
The problem is, they don't ref the same object.. because you cannot alter the mat variable in the class. You get a copy of a reference and you're altering the copy. If you want to be able to modify a reference, you should wrap it in a class. Then you'll get a copy of the wrapper reference, but the Class1 field is unique.
Class wrap example:
public class ClassType
{
public string a { get; set; }
public int b { get; set; }
}
public class Class1
{
public ClassType[] classType;
}
public class Wrapper
{
public Class1 WrappedClass1;
}
public class Class2
{
public Wrapper Wrapped;
public Class2(Wrapper wrapper)
{
Wrapped = wrapper;
}
public void ChangeClass1()
{
WrappedClass1.WrappedClass1 = new Class1();
}
}
Class1 class1 = new Class1();
Wrapper wrapper = new Wrapper();
wrapper.WrappedClass1 = class1;
Class2 class2 = new Class2(wrapper);
class2.ChangeClass1();
MessageBox.Show(wrapper.WrappedClass1 == class2.Wrapped.WrappedClass1); // <--- true

Constructor is not called

public class Unit
{
public int UnitId { get; set; }
public Engine EngineStuff { get; set; }
}
public class Engine
{
public int PS { get; set; }
public int MaxSpeed { get; set; }
}
var unit = new Unit();
unit.UnitId = 3; //OK because Unit-constructor was called
unit.EngineStuff.PS = 200; //error, because EngineStuff-constructor obviously wasn't called.
How can this "inner" constructor be called?
I thought it initializes it automatically?
How can I simply assign a value to the property "EngineStuff.PS"?
You have to instantiate object's properties explicitly:
public class Unit
{
public Unit()
{
EngineStuff = new Engine();
}
}
Or if you want to manually control when to instantiate:
var unit = new Unit();
unit.UnitId = 3;
unit.EngineStuff = new Engine();
unit.EngineStuff.PS = 200;
or simpler:
var unit = new Unit { UnitId = 3 };
unit.EngineStuff = new Engine { PS = 200 };
Simply you need to initialize EngineStuff in either Unit constructor or just before using it.
public class Unit
{
public Unit()
{
EngineStuff = new Engine();
}
public int UnitId { get; set; }
public Engine EngineStuff { get; set; }
}
Or :
var unit = new Unit();
unit.UnitId = 3;
unit.EngineStuff = new Engine():
unit.EngineStuff.PS = 200;
EngineStuff is just a reference, you need to set its value to an Engine object that you create, either in the Unit constructor, a property initializer, or plain code.
So either:
// Constructor
public class Unit
{
public Unit() { EngineStuff = new Engine(); }
public int UnitId { get; set; }
public Engine EngineStuff { get; set; }
}
Or
// Property initializer
var unit = new Unit
{
UnitId = 3,
EngineStuff = new Engine { PS = 200 }
};
Or
// Plain code
var unit = new Unit();
unit.UnitId = 3;
unit.EngineStuff = new Engine { PS = 200 };
No, you need to set it explicitly like below cause EngineStuff is of type Engine and so you will have instantiate it first before accessing any of it's member.
unit.EngineStuff = new Engine { PS = 10, MaxSpeed = 2000 };
(OR) you can change your Unit class to have EngineStuff as a getter property and have the instance created there like below
public Engine EngineStuff
{
get
{
return new Engine();
}
}
Then you can access it
var unit = new Unit();
unit.UnitId = 3;
unit.EngineStuff.PS = 100;
Addition to other answers, you can define a getter property to create the instance when you need it first time:
public class Unit
{
public int UnitId { get; set; }
private Engine engineStuff;
public Engine EngineStuff
{
get
{
if (engineStuff == null) engineStuff = new EngineStuff();
return engineStuff;
}
}
}

Object within an object is null

I'm using C# and have created an object to send to a JSON service that looks like this:
public class SendRequest
{
public string id { get; set; }
public string case { get; set; }
public string method { get; set; }
public Volume value { get; set; }
}
public class Volume
{
public int level;
public bool mute;
}
I can code hint when setting the sub object:
var _req = new SendRequest();
_req.value.mute = false;
_req.value.level = 50;
But when the program is run, the sub-object itself is null (_req.value = null) and the two items under that object don't show.
Why is this happening?
You need to initialize the "value" to something.
Add this constructor to your SendRequest class:
public SendRequest(){ value = new Volume(); }
You can use object initializers
var _req = new SendRequest()
{
value = new Volume()
{
mute = false,
level = 50,
},
};
at this point method is null
public string method { get; set; }
longer but what you can do is
private string method = string.empty;
public string Method { get {return method;} set {method = value;} }
value is just a bad name
private Volume volume = new Volume();
public Volume Volume { get {return volume;} set {volume = value;} }
or
volume = new Volume (mute = false, value.level = 50);

Changing a class's property from another class

I have a class with properties:
public class TaskConfiguration
{
public string Task_Name
{
get; set;
}
public string task_id
{
get; set;
}
}
And somewhere in the code I have a method to set the properties of the class early on upon program execution:
public class TaskManagingProcess
{
public void InsertTaskProperties()
{
TaskConfiguration tc = new TaskConfiguration();
tc.Task_Name = "Sample Task";
tc.task_id = "1";
}
}
Later in execution, in another class, I want to modify the properties of the TaskConfiguration class, but I'm not sure how. If I use the following, it will not work because it creates a new instance of the TaskConfiguration class.
TaskManagingProcess tmp = new TaskManagingProcess;
tmp.InsertTaskProperties();
So how can I do this?
You want to pass the object:
public void InsertTaskProperties(TaskConfiguration config) {
config.Task_Name = "Sample Task";
config.task_id = "1";
}
Then:
TaskManagingProcess tmp = new TaskManagingProcess();
TaskConfiguration config = new TaskConfiguration();
tmp.InsertTaskProperties(config);
(I am making an awfully large assumption about your code.. but this should give you the basic idea)
It looks to me like TaskManagingProcess is a proxy class that's why I would recommend something like:
public class TaskConfiguration
{
public string Task_Name
{
get;
set;
}
public string task_id
{
get;
set;
}
}
public class TaskManagingProcess
{
private TaskConfiguration taskConfiguration;
public TaskManagingProcess(TaskConfiguration taskConfiguration)
{
this.taskConfiguration = taskConfiguration;
}
public void InsertTaskProperties(string taskId, string name)
{
taskConfiguration.task_id = taskId;
taskConfiguration.Task_Name = name;
}
}
So at the end you could do this (see below) and easily add code to handle the access at your TaskConfiguration object:
TaskConfiguration taskConfiguration = new TaskConfiguration() { task_id = "1", Task_Name = "Sample Task" };
TaskManagingProcess taskManaginProcess = new TaskManagingProcess(taskConfiguration);
taskManaginProcess.InsertTaskProperties("2", "Sample Task 2");

Categories

Resources