how can i get the value of another variable in C# - 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);

Related

Unity, C#, pointer workaround?

I have a field of type Color, let's call it objectColor. I want objectColor "point" to a gameobject that has a color field. For example, the background color of the camera. Or the color of a sprite renderer. When I try "objectColor = mainCamera.backgroundColor" for example, it copies the main cameras background color at that time, and is not linked. I am used to pointers and C++. If I was in C++ I would just make a pointer of Color type, make it point to what mainCamera.backgroundColor is pointing to, and then change the color that way. Any suggestions?
No simple way to do that in C#. You could either hold reference to the class, that owns Color field, but this will prevent you from changing colors of different object types (not sure it is bad actually). Or you could make class wrappers around all objects with color changing functionality and use them through common interface.
interface IColorChange {
void SetColor(Color color);
}
class CameraWrapper : IColorChange {
public void SetColor(Color color){
m_camera.backgroundColor = color;
}
}
Actually, if you think about it, storing member pointer in c++ is also not such a great idea. Class instance could die any time and you will be left with a dangling pointer without any way to know about it.
One somewhat unusual way (but not necessarily bad if documented well) would be to use "properties". Those are variables which automatically call their custom setter and getter methods when accessed. You cannot avoid separately keeping a reference to the camera instance with them either however.
Here an unity-independent example: https://dotnetfiddle.net/oxBqXV
using System;
public class Camera
{
public int color = 20;
}
public class Foo // most likely should inherit from MonoBehavior
{
Camera _camera;
public int cam_color_ptr // property
{
get
{
return _camera.color;
} // get method
set
{
_camera.color = value;
} // set method
}
public void Start()
{
// of course you should acutally get the reference here
// or have _camera a serializable field to assign in the editor.
_camera = new Camera();
}
public void Print()
{
Console.WriteLine("The camera color is: " + cam_color_ptr);
}
}
public class Program
{
public static void Main()
{
Foo foo = new Foo();
foo.Start();
foo.Print();
}
}

Inheritance-Need Guidance

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.

With a struct that is a property, what is the standard for updating a value in the struct?

I'm new to C#, and I'm working with a class that has a Rectangle field. I've read that Properties are the most accepted way to declare public fields, so I tried something like this:
public class MyClass
{
public Rectangle MyBox { get; set; }
public UpdateBox(int x, int y)
{
MyBox.X = x;
MyBox.Y = y;
}
}
It won't let me do MyBox.X = x because (from what I've read), Rectangle is a struct, and the getter returns a copy of the Rectangle, so I would not be modifying the value I want.
What is the standard for updating fields like this? I've found two solutions so far:
Creating a new Rectangle to store in the variable:
public class MyClass
{
public Rectangle MyBox { get; set; }
public UpdateBox(int x, int y)
{
MyBox = new Rectangle(x, y, MyBox.Width, MyBox.Height);
}
}
but this seems like it would not be very memory efficient. Then there is just not making Rectangle a property:
public class MyClass
{
public Rectangle MyBox;
public UpdateBox(int x, int y)
{
MyBox.X = x;
MyBox.Y = y;
}
}
What is the standard for this kind of functionality?
By convention you can use a struct as a field and access its internal fields directly, if you want to use it as a property, then make a proper setter for it.
I, personally only use struct types as fields other than properties, maybe a read only property for public access (for encapsulation purposes), grants me safety and general organization of my code.
Your 3rd block of example code is the most correct form in my view, and no its not memory inefficient, Rectangle MyBox is already allocated in memory and already consuming its most by the time the constructor is called.
Also, let us keep in mind here, a property is a "shortcut" function to access some data, but if this data ought to be stored somewhere and wont likely change (default get/set accessors), then it's not any different from a normal field.
This is my favorite way of dealing with this:
public class MyClass
{
private Rectangle _MyBox; // or protected idk.
// This is public and read only.
public Rectangle MyBox { get { return _MyBox; } }
public UpdateBox(int x, int y)
{
_MyBox.X = x;
_MyBox.Y = y;
}
}
The clearest approach for non-speed-critical applications is to use the pattern:
var temp=myThing.TheProperty;
temp.X = whatever;
temp.Y = whatever;
myThing.TheProperty = temp;
If the structure behaves as a bunch of independent variables fastened together with duct tape, the above approach will avoid having to either have the client code know about all of its fields, or have the struct include lots of boilerplate WithX, WithY, etc. factory methods.
If speed is important, then one should either have structures exposed in fields or arrays [as opposed to other collection types], or--if one wants to retain encapsulation--include accessor methods:
delegate void ActionRR<T1,T2>(ref T1 p1, ref T2 p2);
void ActOnBounds<TExtra>(ref Rectangle bounds, ActionRR<Rectangle, TExtra>proc, ref TExtra extra)
{
proc(ref _bounds, ref extra);
}
Note that generating delegates to call ActOnBounds will make it slow, but it may be used efficiently by passing a static delegate and a ref valuetype. Unfortunately, while C# includes lots of nice syntactic sugar for closures, it does not provide such help with constructs like the above.

Why is this method Impure?

I read this answer: https://stackoverflow.com/a/9928643/16241
But I obviously don't understand it because I can't figure out why my method is impure. (The method in question is ToExactLocation()).
public struct ScreenLocation
{
public ScreenLocation(int x, int y):this()
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
public ExactLocation ToExactLocation()
{
return new ExactLocation {X = this.X, Y = this.Y};
}
// Other stuff
}
Incase you need it here is the exact location struct:
public struct ExactLocation
{
public double X { get; set; }
public double Y { get; set; }
// Various Operator Overloads, but no constructor
}
And this is how I call it:
someScreenLocation = MethodThatGivesAScreenLocation();
if (DestinationLocation == someScreenLocation.ToExactLocation())
{
// Do stuff
}
When I do that, ReSharper flags it with "Impure Method is called for readonly field of value type."
Why is it saying that? And what can I do to make it go away?
It's not pure because it does not return a value dependent only on its input. When the value of X or Y changes so does the return value of ToExactLocation, i.e., its output depends on internal, mutable state.
Additionally, the setters for X or Y in ExactLocation may mutate the input. The getters of ScreenLocation may as well.
someScreenLocation is a readonly field and is a value type. You are calling ToExactLocation on a value, i.e., a readonly field. When you access a reaodnly value type a copy is created as to avoid mutating the value itself. However, your call may mutate that value, which, in many cases, is not what you want as you will be mutating a copy. This is why you get a warning.
In this case, you can ignore it, but I would avoid mutable value types in general.
EDIT:
Let me attempt to simplify...
struct Point
{
int X;
int Y;
bool Mutate() { X++; Y++; }
}
class Foo
{
public readonly Point P;
Foo()
{
P = new Point();
P.Mutate(); // impure function on readonly value type
}
}
When Mutate() is called, a copy of P is created and passed along with the method. Any mutation of P's internal state will be irrelevant as it mutates a copy.
One of the conditions of a Pure Method is that its output (return value) is wholly dependent on its input (arguments).
Your .ToExactLocation() method is not pure, because its output depends both on the input arguments and also on the current value of a mutable struct.
Resharper doesn't like this, because mutable structs are bad (don't use them). I expect the error would go away if you either changed your code to use a class instead of a struct or redesigned the struct so the the .X and .Y members could only be set by the constructor.
Reading the answer, I found out that pure functions are necessarily like functions in mathematics. f(x) = x^2 + 2x + 10 will always return 10 if x is 0.
So ToExactLocation() must return the same values each time it is called, regardless changes to object since initial creation, for it to be called "pure".
There are 2 meaning of "pure function": one theoretical (no side effects/no dependency on mutable state) and another is what ReSharper thinks about functions.
From theoretical point of view your function is not pure because it depends on mutable state. Sample:
var someScreenLocation = new ScreenLocation(1,1);
var locationOne = someScreenLocation.ToExactLocation();
var locationTwo = someScreenLocation.ToExactLocation();
someScreenLocation.X = 3;
var locationThree = someScreenLocation.ToExactLocation();
For method to be pure it can change its result only based on input (not at all as in this case since there is no arguments). But you can clearly observe that locationOne and locationTwo are the same (good sign so far), but unfortunately locationThree is different even if the input (arguments to the function) still the same.
You can make it theoretically pure by making X and Y readonly (and adding constructor).
Even after the change ReSharper will still think it is not pure - to convince it you can use Pure attribute to mark it as pure.
Note that ReSharper marks usage of "impure" functions even in constructor of the class with readonly field. Sample below shows ReSharper warnings:
struct Point
{
public int X;
public int Y;
public Point(int x, int y){X = x;Y = y;}
public void Mutate(){X++;}
public Point TheoreticallyPure(){return new Point(1, 1);}
[Pure] public Point MarkedPure(){ return new Point(1, 1);}
}
class WithReadonlyField
{
public readonly Point P;
public WithReadonlyField()
{
P = new Point();
P.TheoreticallyPure(); // impure function on readonly value type
P.MarkedPure(); // return value of pure not used
P.Mutate(); // impure function on readonly value type - modifies P.
P = new Point().MarkedPure(); // ok to modify P multiple times.
}
public void NormalMethod()
{
P.Mutate(); // impure function on readonly value type, no changes to P
}
}
C# allows modification of readonly fields up to the end of constructor, but ReSharper marks usages of all "impure" functions there too (Note that Mutate function in constructor actually changes value of readonly field P, unlike in NormalMethod where it has no effect).
"readonly... assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class"
Most likely this behavior of ReSharper is for consistency and to avoid cases where moving perfectly valid code changes behavior completely.
It would be better to model this as a static method (on either class) and would get rid of the impure warning. Explanation omitted, as the other answers covers the why already.
Example:
public static ExactLocation ToExactLocation(ScreenLocation loc)
{
return new ExactLocation {X = loc.X, Y = loc.Y};
}
or use an extension method
public static ExactLocation ToExactLocation(this ScreenLocation loc)
{
return new ExactLocation {X = loc.X, Y = loc.Y};
}
Not really sure about the cause, and I'd put this as a comment if it would format correctly...
Wouldn't you want something like:
var someScreenLocation = MethodThatGivesAScreenLocation();
if (DestinationLocation.X == someScreenLocation.ToExactLocation().X &&
DestinationLocation.Y == someScreenLocation.ToExactLocation().Y)
{
// Do stuff
}

force get/set access of private variables for private properties

If I have a private variable that I want to have some internal validation on, and I want to keep that validation in one place, I put it behind a getter/setter and only access it thorugh that getter/setter. That's useful when dealing with public properties, because the other code cannot access the private variable, but when I'm dealing with object inside the class itself, is there any way to enforce the getter/setter?
private int _eyeOrientation;
private int eyeOrientation
{
get
{
return _eyeOrientation;
}
set
{
if (value < 0)
{
_eyeOrientation = 0;
}
else
{
_eyeOrientation = value % 360;
}
}
}
The issue here being that the other functions in the class may accidentally modify
_eyeOrientation = -1;
which would throw the program into a tizzy. Is there any way to get that to throw a compiler error?
Sounds like you need a angle type.
// Non mutable Angle class with a normalized, integer angle-value
public struct Angle
{
public Angle(int value)
{
Value = value;
}
private angle;
public Value
{
get { return angle; }
private set { angle = Normalize(value); }
}
public static int Normalize(int value)
{
if (value < 0) return 360 - (value % 360);
return value % 360;
}
}
public class SomeClass
{
public Angle EyeOrientation { get; set; }
}
If you have a certain kind of value, like angles, money, weight or whatever, it is always a good praxis to make it a own type, even if the value itself is stored in a int, decimal etc. This type makes your interfaces clearer and typesafe. It is not the same if you expect an Angle or a integer value as argument of some method.
In general, you shouldn't worry about this. Class members can still use the properties, if you don't want to put the checking in the class itself.
If your class is getting so large that you no longer trust methods inside the class, I'd think that it's time to start refactoring and breaking this into smaller classes that are more easily managable.
You could possibly define it in a nested class.
public class NeedsEye
{
Eye _eye = new Eye();
public NeedsEye()
{
// now, here, any access to the property must be made through the
// _eye variable. The Eye class has access to any of the properties
// and members of the NeedsEye class, but the NeedsEye class has not
// any access to members of the Eye class.
}
private class Eye
{
private int _orientation;
public int Orientation
{
get { return _orientation; }
if (value < 0)
{
_eyeOrientation = 0;
}
else
{
_eyeOrientation = value % 360;
}
}
}
}
You can mark the field as obsolete so that the compiler will generate a warning if you try to access it, and then suppress that warning for the property getter/setter.
The warning codes that you'd need to suppress are CS0612 for the plain Obsolete attribute and CS0618 if the attribute has a custom message.
In general I'd consider this a bit of a hack and try to avoid it if possible. A better solution would be to comment the code appropriately and train your fellow developers so that they'll do the right thing.
[Obsolete("Please use the EyeOrientation property instead.")]
private int _eyeOrientation;
public int EyeOrientation
{
#pragma warning disable 612, 618
get
{
return _eyeOrientation;
}
set
{
_eyeOrientation = (value > 0) ? value % 360 : 0;
}
#pragma warning restore 612, 618
}
Just put your private attribute and public getters/setters into a private class.
Then only the getter and setter can access the private attribute.
It is overkill but would work. :)
Depending on your tools you could look into enforcing a coding convention not allowing direct access to a private member outside a get/set
Might be some more work but you won't have to create a series of wrapper classes.

Categories

Resources