Inheritance-Need Guidance - c#

I am a novice programmer, so sorry if this is a really stupid question. I need to pass a value from one class to another. If I am not mistaken, this would be done through inheritance, but there seems to be something I am missing. Any help would be welcome. I am writing in C# within Unity.
public class baseStats{
private int STAMINA;
public static int Stamina{
get{return STAMINA;}
set{STAMINA = value;}
}
}
The above is a sample of my parent class. Here is my child class:
public class Profile : baseStats {
private static int PROFILE_STAMINA;
private void Stats ()
{
PROFILE_STAMINA = Stamina;
}
public static int profileStamina
{
get{return PROFILE_STAMINA;}
}
}
In a third script I created for the purposes of debugging, I wrote:
public class debug:MonoBehaviour{
void Start(){
Debug.Log(Profile.profileStamina.ToString());
}
}
It says I need an object reference for the non-static field, method, or property
'Profile.Profile.Stamina'. Easy fix: make everything static (I believe I need to make constructors or something like that to avoid having to use static all the time. A little help with that would be great!). Once error-free, I ran the program and the console outputs 0 for my profile stamina. I am really confused as to what is going on. Sorry this is such a long post, and thanks for any help I get.

I need to pass a value from one class to another. If I am not
mistaken, this would be done through inheritance.
No, you don't need inheritance to pass values from one class to another. If you don't know what inheritance is, you shouldn't be using it. It's very likely you don't need it. The-same thing applies to the static keyword. New programmers tend to make everything static when they don't know what the new keyword is used for.
Simply create a new instance of the Stats script inside the Profile constructor script. To use the Profile script, create a new instance of it which will automatically call the constructor that will create a new instance of the Stats script. You shouldn't be doing this with static variables and functions. Totally unnecessary. Values can be passed to another script with auto property or function but my solution used auto property to make it simple.
public class Stats
{
private int STAMINA;
public int Stamina
{
get { return STAMINA; }
set { STAMINA = value; }
}
}
public class Profile
{
private Stats stats;
private int PROFILE_STAMINA;
//Init only
public Profile()
{
stats = new Stats();
}
//Init with Stats stamina and profileStamina stamina values
public Profile(int stamina, int profileStamina)
{
stats = new Stats();
stats.Stamina = stamina;
PROFILE_STAMINA = profileStamina;
}
//Stamina From Profile
public int profileStamina
{
get { return PROFILE_STAMINA; }
set { PROFILE_STAMINA = value; }
}
//Stamina From Stats
public int Stamina
{
get { return stats.Stamina; }
set { stats.Stamina = value; }
}
}
Usage:
public class debug:MonoBehaviour{
Profile profile = null;
void Start()
{
//Creata new profile and set Stats stamina and ProfileStamina stamina values
profile = new Profile(10, 5);
profile.Stamina = 60;
profile.profileStamina = 60;
Debug.Log(profile.profileStamina.ToString());
}
Also take time and learn about Classes,Properties.

You're trying to access a non-static from a static property.
This code is the main problem:
public static int Stamina{
get{return STAMINA;}
set{STAMINA = value;}
}
STAMINA is defined as private int STAMINA. It isn't static. Quite simply, this means that inside every object of the type baseStats you have an int called STAMINA you can fill in. However, you're not working on an object there; you're in a static function, which is something that can be executed without an object. Since there is no object, there is no STAMINA int either; there's no object to get or fill in that property on.
On that note, your function profileStats() has the same issue; it tries to access the non-static STAMINA as well, again without having any kind of object. Any reference to just plain STAMINA is actually to this.STAMINA, and inside a static, there's no this.
I'm not sure what the purpose of this whole setup is; personally I'd avoid using statics containing global data like that. Instead I'd just keep an object around containing the necessary properties which is simply passed on to any functions that need to access the data in it. But anyway, from what I can see, you simply forgot to put static on that private int STAMINA.
Side note: this is completely unrelated to inheritance. Since Stamina is a public static property, and statics can't be inherited (except in some peculiar advanced cases with inherited generics), your "child class" never even needs the parent class as parent, as long as it references baseStats.Stamina instead of STAMINA. This can easily be shown by making both classes static.

Related

C# Make a class return its instance without a function or variable

So I've been working with classes with single instances in Unity for a while and generally do this:
class PublicThings {
public static PublicThings I; // instance of this class
public int Score;
void Start { I = GetComponent<PublicThings>(); }
}
Usage: PublicThings.I.Score = 10;
Which works pretty well. However, I've been curious as to whether or not it's possible to have the instance of the class be returned without having to type .I after the class.
So basically here's how it would look instead:
PublicThings.Score = 10;
This question seems like it's relevent but I'm having trouble getting it to work.
Is this possible? If so, how would it be done?
Three options to do what you are looking to do:
Make a static property/field with the static keyword in the PublicThings class
Make a ScriptableObject and attach it to the item that is calling it (video tutorial)
Utilize the Singleton Pattern (I would suggest avoid using this method before trying the other two)
Also it's worth noting that the Singleton Pattern doesn't necessarily solve your problem. You will still have to call something like PublicThings.instance.Score.
Hope this helps.
Singleton pattern is the way to go.
Also, with lazy instantiation.
public class PublicThings
{
private static PublicThings _instance;
// Your private constructor
private PublicThings() { }
public static PublicThings Instance
{
get
{
if (_instance == null)
{
// Construction of instance logic here
_instance = new PublicThings();
}
return _instance;
}
// No setter, read-only property
}
// Decide if Score is a read-only property or not.
public int Score { get; set; }
}
Whener the single instance of PublicThings is required, it will be constructed and then stored. A second access to the instance will provide the stored one.
[Test]
public void WithTwoAccess_ToSingleInstance_MustBeTheSame()
{
var things1 = PublicThings.Instance;
var things2 = PublicThings.Instance;
Assert.AreSame(things2, things1);
// Asserts true
}
If your Score property must be set once, just change que Instance property to a method (commonly called GetInstance) which expects the value of Score.
Hope it helps.

how can i get the value of another variable in C#

I am trying to write some code in C# with unity where i have an object who's position I need to know for my script to work. I was trying to use a pointer as that's what I thought was used. It said i had to use an unsafe tag which made me think i was doing something wrong. I am a little new to this and so far i have most of my knowledge with C++ as that's what i have learned in class. I tried looking it up but i could not find it. this is basically what i have right now.
using UnityEngine;
using System.Collections;
public class SGravSim : MonoBehaviour {
public GameObject moon;
public GameObject earth;
private struct Cords
{
public float* x
{
get
{
return x;
}
set
{
if (value != 0) <== this thing is realy just a placeholder
x = value;
}
}
public float* y
{
get
{
return y;
}
set
{
if (value != 0) <== this this is only in here for now
y = value;
}
}
public void DisplayX()
{
}
}
private Cords moonLocation;
private Cords earthLocation;
private Cords SataliteLocation;
// Use this for initialization
void Start () {
moonLocation.x = moon.transform.position.x;
moonLocation.y = moon.transform.position.y;
earthLocation.x = earth.transform.position.x;
earthLocation.y = earth.transform.position.y;
SataliteLocation.x = this.transform.position.x;
SataliteLocation.y = this.transform.position.y;
}
// Update is called once per frame
void Update () {
Debug.Log(moon.transform.position.x);
//
// Summary:
// The position of the transform in world space.
float yMoon = moon.transform.position.x
print(moonLocation.y);
}
}
I was planing on making the set so that you could not add anything to it.
I guess I could write out the whole earth.position.x thing every time I need to use it I was just trying to see if there was a better way to do it and also a way where I cant mess with the variable as all I want to do is read it.
You can use private set in the automatic properties :
public float X {get; private set;}
This way only your class will be able to set the variable but any other class wouldn't.
You shouldn't use pointers in c# except for really specific cases.
The solution several people gave you here is good:
public float X {get; private set;}
It is called a property and is one of the nice possibilities in c# to avoid creating getters and setters.
You say you have some knowledge in c++, but c# is actually closer to higher languages such as java. You should focus on the Object Oriented way to code and forget about low level pointers, especially using Unity.
You can use:
private float x;
public float X
{
get
{
return x;
}
}
Now you only set x from within your class.
You get the unsafe tag warning, because you try to use pointers, which are actually unsafe. There might be use-cases for that, but in C# you generally use reference types and value types. In C# a struct is a value type, so it will behave differently compared to a reference type, as you can read here, which is also why Gubr has suggested to use a class instead of a struct. Last but not least, there is a difference in how they are stored, just google C# heap and stack.
I haven't used structs that much in C# yet, so I just created a new project and played a bit around.
So I used your code, which also could just look like this:
private struct Cords
{
public float x, y;
public void DisplayX(){}
}
As the others have mentioned, you could leave out the set or make it private and add a constructor. Mind you, a private set doesn't equal to not defining it in auto-properties. Instead, it will create a readonly field. However, you have to call the new operator in both cases to set the value:
private struct Cords
{
public float X { get; }
public float Y { get; }
public void DisplayX(){}
public Cords(float x, float y)
{
X = x;
Y = y;
}
}
And here we create a new Cords:
Cords earth = new Cords(10.005f, 12.689f);

Defining both Private Field and Property vs just Property

Following OOP's best practices, is it better to have this code:
class Car {
private Driv driver;
public Driv Driver {
get { return driver; }
set { driver = value; }
}
}
Or this one?
class Car
{
public Driv Driver { get; set; }
}
While the second version is shorter, I feel like I'm breaking the main premise of the Encapsulation concept:
EVERY class should keep its privates to itself.
Hope the answer is not too trivial.
There really is no difference. If no private variable is created by the user then the code will be generated automatically for the private field. However, if the user wishes to do additional logic in the getter or setter of the property then declaring a private field is necessary.
Your first example is what's called a Property with a backing field
The second is called an Automatic property.
The purpose of a property with a backing field is so that you can control access to your private properties.
So... If for instance you want to, make a calculation before returning the value of your private field, you could do it in the one with the backing field.
Or lets say you have a car object with 10,000 miles on the clock... you would probably want to only increment its value using the Drive method, and hide the setter of the Property with the backing field
void Main()
{
var car = new Car();
car.Drive();
Console.WriteLine (car.Miles);
}
public class Car
{
private int miles;
public Car()
{
miles = 10000;
}
public int Miles
{
get
{
return this.miles;
}
}
public void Drive()
{
this.miles += 100;
}
}
You are not breaking encapsulation with the second approach. The second approach is syntactic sugar to make property definition less verbose. The benefit of this approach is that in the future if you need to modify the getter or the setter, you are setup to do so and will not break the API contract.
C#'s properties are simply syntactic representations of some underlying methods and variables. Essentially, the compiler turns:
public int Height { get; set; }
into:
private int height;
public int getHeight() {return height;}
public int setHeight(int h) {height = h;}
So, no you are not defying OOP encapsulation, but instead syntactically simplifying it. You could also do something like public int Height {get;} which is a nice way to create an immutable class member. It simply creates the property without a set method, so only the class itself can alter it.
Now, you only need to use properties with backing fields if you wish to do additional tasks when getting or setting a variable, such as raise an event, or update another variable. The compiler would turn:
private int height;
public int Height { get {return height;} set {height = value; OnHeightChanged();} }
into:
private int height;
public int getHeight() {return height;}
public int setHeight(int value) {height = value; OnHeightChanged();}
Hope this helps!

what the best way to declare a property

I'm switching from Objective-C to C# to start using the Unity engine. So I'm trying to soak in all the C# differences. Obj-C has the #synthesize that auto creates the getters and setters. To to be honest they're sort of new to me. In Obj-C I'd often do:
#synthesize myProperty = _myProperty;
Then use the _myProperty in the local class code and access that property outside of this class using myProperty. Or more accurately classInstance.myProperty.
Also in Obj-C you can declare a property to be readonly and not worry about accidentally changing it's value outside the class.
In C# I'm trying to write proper object oriented code and I struggle with this. I'm a C coder at heart and am comfortable having access to everything everywhere, which I know is bad and unnecessary. I also don't want to expose tons of properties to the GameObject Inspector. I prefer to do as much programmatically as possible.
So what is the best way to declare properties so I can access them from another class but also so they are not exposed in the Inspector? Here are some possibilities that I've encountered and used:
// 1. public static - public without being exposed in inspector
public static int myProperty;
// 2. the public _text doesn't appear in the inspector but the text one does.
public string _text;
public string text {
get { return _text; }
set {
_text = value;
}
}
// 3. private _underscore version with no setter - does removing the set make it read only?
private float _current;
public float current {
get { return _current; }
}
// 4. creating my own getter function
private int myValue;
...
int GetMyValue() {
return myValue;
}
Also.. I read somewhere that in .NET you shouldn't use underscores in property names. I don't really know what the underscore version of the property does or represents. I thought in Obj-C it effected the scope, but don't really know.
Am I even correct in calling variables properties?
Someone suggested prop tab tab which produces this:
public object MyProperty {
get;
set;
}
Unfortunately that doesn't really answer my question about read only. Is an int or string even an object? It's not in Obj-C.
Public variables (not fields) are shown in the Unity inspector. If you want a public variable to be hidden, you can preface it with NonSerialized, like this:
[System.NonSerialized]
public bool m_HideWhenInactive = false;
You can also avoid this problem entirely by making it a property. No properties are shown in the inspector:
public bool m_HideWhenInactive { get; set; }
As a fun bonus (not your question, I know), you can have a property that's world-read, private-write:
public bool m_HideWhenInactive { get; private set; }
And finally, if you DO want a variable to be serialized and stored in a prefab, but you don't want the designers editing it (if you intend to write a custom editor class), there's a different annotation for that:
[HideInInspector]
public bool m_HideWhenInactive = false;
Static fields are never shown in the inspector.
The NonSerialized and HideInspector attributes are the two options you must consider to hide members of the class from the Unity inspector. NonSerialized is not specific to Unity, HideInspector is specific to Unity. Unity looks for both of these attribute in your compiled code to determine what gets exposed in the inspector.
If you want a publicly read only property you declare it like so...
[System.NonSerialized]
private string _text;
/// <summary>
/// Gets the Text
/// </summary>
/// <remarks>May be set within this class or derived classes</remarks>
public string Text {
get { return _text; }
protected set {
_text = value;
}
}
You seem to be having issues with the meaning of access modifiers...
See this page...
https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx
Briefly...
public = accessible from anywhere, do not declare backing variables on properties as public, otherwise people can simply skip your property accessor.
protected = accessible within your class and from classes inheriting the class
internal = accessible within the same assembly
protected internal = accessible within the same assembly and from
classes inheriting the class
private = accessible only within your class
You can do away with backing variables simply by declaring
/// <summary>
/// Gets or sets the Text
/// </summary>
public string Text { get; set; }
/// <summary>
/// Gets the current
/// </summary>
public float Current { get; protected set; }
Since the advent of auto-implemented variables, there are no technical reasons for creating properties with backing variables unless you have additional logic you would like executed on the get and/or set.
e.g you wanted to create Observable entities that raise an event when a property is changed...
private int _id;
public int ID
{
get
{
return _id;
}
set
{
if (_id != value)
{
OnIDChanging(value);
ReportPropertyChanging("ID");
_id = StructuralObject.SetValidValue(value);
ReportPropertyChanged("ID");
OnIDChanged();
}
}
}
In terms of coding standards, there are plenty of them on the net. I'd recommend IDesign's...
http://www.idesign.net/downloads/getdownload/1985
You'll notice I changed the casing on the code you posted, the casing I've used adhere's to IDesign's naming guidelines
The correct way to create properties really depends on what it is you're trying to accomplish. If you're only wanting to have a property be created for further use you can create the shorthand way:
public object MyProperty { get; set; }
If more functionality is required, you can add additional functionality, such as:
private int _myInt;
public int MyInt {
get { return this._name; }
set {
if (this._name == 1) {
this._name = value;
} else {
this._name = 0;
}
}
}
The answer of your question is it simply depends on what it is you're looking to achieve and both ways are accepted.
The use of getter and setter methods, such as those found in Java, are frowned upon in C#.
To answer your other question, String is an object in C#. int is a primitive type.
Here's a quick summary of your problems.
There is a so called snippet in C# that allows you to quickly generate code. The quick shortcut for it is typing prop and then pressing tab which would generate a code to something like this.
public int MyProperty { get; set; }
Now if you're going to create fields, and you dont want to expose that to an instance. You should make it private.
Example
private int myVar; // private is not exposed on instances only public properties are
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
Now for static fields, static fields/properties are type accessible. So to hide them, you only have to make them private
Example
private static bool myProp; // can't be accessed on the Program Type
public static bool MyProp { get; set; } // can be accessed on the Program Type
class MyClass
{
public MyClass()
{
Program.MyProp = true;
Program.myProp= true; // wont build
}
}
If you want it to be readonly and prevent modification, you can do it like this.
public int MyProperty { get; private set; } // can get but not set
private int myVar;
public int MyProperty
{
get { return myVar; } // same as the top but with a field
}
For a deeper and better understanding, please do read about What are Access Modifiers in C#?
Property patterns in the context of the Unity engine tend to differ slightly to the 'norm' of C# because of you are often interested in making them tweakable data in the editor. This means serialization.
Unity cannot serialize properties
Unity can serialize fields of primitive types and types inheriting from UnityEngine.Object are serialized references
Unity can serialize list and arrays of the types mentioned above as well
Serialized fields on MonoBehaviours are exposed in the editor and are editable
public fields are serialized by default and private fields if they are marked with the [SerializeField] attribute.
Unity also serializes fields on classes marked with [System.Serializable] if the class is a field on a MonoBehavior
For a more in-depth discussion see: https://blogs.unity3d.com/2014/06/24/serialization-in-unity/
The following pattern is common, the backing field can be set by the developer, without needing to recompile, and cannot be changed by external code at run-time.
[SerializeField]
private int editableInEditor;
public int NotEditableInEditor
{
get { return editableInEditor; }
}
So is this pattern, a lazy-getter.
private DerivedMonoBehaviour component;
public DerivedMonoBehaviour Component
{
get
{
if(component == null)
{
// Note: Using the null-coalescing operator ??
// is inadvisable when dealing with UnityEngine.Object
// references.
// See: https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/
component = GetComponent<DerivedMonoBehaviour>();
}
return component;
}
}

Is it possible to have a bool/string/int/etc that can be accessed by any form in the program?

I've done some research on global variables, and have come up with the fact that static variables should be able to solve my problem. I don't understand how to make these, though. How would I do so? Also, if static variables would not solve my problem, what should I use?
I want to be able to access a string, bool and int in my main form, from another form. Help?
Static variables (or better yet, properties) would likely work. You would declare this as:
// In Form1 (could be internal or public)
public static bool SomeBool { get; set; }
And then, to access, you'd use Form1.SomeBool = true; or if (Form1.SomeBool) {, etc.
That being said, "global" data like this is discouraged for a reason - there is typically some better way to handle this. For example, you might want to make a custom class that holds your data, and pass a reference to an instance of this class to the new form when you create it.
Not only static, it must be public static. You can simply declare it like any other variable, as in public static int x = 1;. Then you can acces it like ClassFoo.x, but you must be in a static context as well.
If you want this information to be held per form instance (an object) then you don't want to use static fields. On the other hand if what you want is to have some information that you can access from any instance (it is shared) of your class form, or in other words, you want to have this information only once... then yes, use static fields.
What you would want to do is something like this:
//partial because I take you are using a form designer.
//and also because the class is gonna have more things than those showed here.
//in particular the example call a method "UseFields" that I did not define.
public partial class MyForm: form
{
private static bool boolField;
private static string stringField;
private static int intField;
private void Method()
{
//Do something with the fields
UseFields(boolField, stringField, intField);
UseFields(IsBoolFieldSet, SomeString, SharedInformation.SomeInt);
}
//You can also wrap them in a property:
public static bool IsBoolFieldSet
{
get
{
return boolField;
}
//Don't put a set if you want it to be read only
set
{
return boolField;
}
}
//Or declare an static property like so:
public static string SomeString { get; set; }
}
//Another good option is to have this information in a separate class
public class SharedInformation
{
public static int SomeInt { get; set; }
}
Please take care with shared state, in particular in a multithreaded enviroment, because this information may be changed without notice by another object that also has access.

Categories

Resources