C
C#ā€¢15mo ago
Itskillerluc

ā” Struct vs Class

When do i use a struct vs a class, There seems to be pretty much no difference between the two except for really small things, what i want is composition, so idk if that helps. i think a struct is waht i should use for that right?
71 Replies
sibber
sibberā€¢15mo ago
reference vs value type is a big difference
Itskillerluc
Itskillerlucā€¢15mo ago
why is it really that big of a deal
sibber
sibberā€¢15mo ago
having a reference to something vs the thing itself changes a lot of things
Itskillerluc
Itskillerlucā€¢15mo ago
like i dont rly understand what it would change
sibber
sibberā€¢15mo ago
like how assignment works when you pass a class instance to a method, your actually passing a reference to the actual instance
Itskillerluc
Itskillerlucā€¢15mo ago
well i know that so if you change it it changes everywhere
sibber
sibberā€¢15mo ago
yes
Itskillerluc
Itskillerlucā€¢15mo ago
and i imagine that doesnt happenw ith a struct then, but even then that doesnt sound like a big deal
sibber
sibberā€¢15mo ago
structs on the other hand are copied it is structs have some other limitations too as a general rule of thumb, default to classes
Itskillerluc
Itskillerlucā€¢15mo ago
so https://paste.ofcode.org/37PNwYAx6seZZWQt6MVij65 is this the way to do it? or should i do it a diff way oh ok i guess ill use a class then
Thinker
Thinkerā€¢15mo ago
Unity's Vector2 and Vector3 are structs, because they essentially act as numbers. You wouldn't want to be able to change the x component of a vector and have that be reflected everywhere else that you've passed that vector to. Imagine for instance that you set an object's position to a vector, then you also pass that same vector to a method which saves it somewhere else. Now if something completely unrelated comes along and changes that vector, you really wouldn't want that to also change the position of the object.
Itskillerluc
Itskillerlucā€¢15mo ago
oh ye i should use a class because i want to be able to change this variable
sibber
sibberā€¢15mo ago
unless what you're writing represents a single logical value (and its size is relatively small), e.g. a date, a vector, etc
Itskillerluc
Itskillerlucā€¢15mo ago
ah ye so this is wrongly used
sibber
sibberā€¢15mo ago
yes
Thinker
Thinkerā€¢15mo ago
What if you did
Vector3 vec = new Vector3(1, 2, 3);
transform.position = vec;
DoStuff(vec, "foo", bar); // Whoops, this method edited the vector, and now the transform.position has also changed!
Vector3 vec = new Vector3(1, 2, 3);
transform.position = vec;
DoStuff(vec, "foo", bar); // Whoops, this method edited the vector, and now the transform.position has also changed!
sibber
sibberā€¢15mo ago
Choosing Between Class and Struct - Framework Design Guidelines
Learn how to decide whether to design a type as a class, or to design a type as a struct. Understand how reference types and value types differ in .NET.
Itskillerluc
Itskillerlucā€¢15mo ago
i changed it to a class now is there a way to do what i did smalelr well
sibber
sibberā€¢15mo ago
do what
Itskillerluc
Itskillerlucā€¢15mo ago
public enum MovementType {Sprinting, Walking, Sneaking}

[Serializable]
public class Movement
{
public MovementType movementType;
public float sprintSpeed;
public float walkSpeed;
public float sneakSpeed;

public Movement(MovementType movementType, float sprintSpeed, float walkSpeed, float sneakSpeed)
{
this.movementType = movementType;
this.sprintSpeed = sprintSpeed;
this.walkSpeed = walkSpeed;
this.sneakSpeed = sneakSpeed;
}
}

public Movement movement = new(MovementType.Walking, 20, 10, 3);
public enum MovementType {Sprinting, Walking, Sneaking}

[Serializable]
public class Movement
{
public MovementType movementType;
public float sprintSpeed;
public float walkSpeed;
public float sneakSpeed;

public Movement(MovementType movementType, float sprintSpeed, float walkSpeed, float sneakSpeed)
{
this.movementType = movementType;
this.sprintSpeed = sprintSpeed;
this.walkSpeed = walkSpeed;
this.sneakSpeed = sneakSpeed;
}
}

public Movement movement = new(MovementType.Walking, 20, 10, 3);
that part
sibber
sibberā€¢15mo ago
unrelated, but im not a fan of nesting types
Itskillerluc
Itskillerlucā€¢15mo ago
wher am i nesting types
sibber
sibberā€¢15mo ago
Movement is inside CharMovement
Itskillerluc
Itskillerlucā€¢15mo ago
oh
sibber
sibberā€¢15mo ago
which should probably be called CharacterController
Itskillerluc
Itskillerlucā€¢15mo ago
well ye but otherwise i have to create a new script and idk what to do with the script that arleady exists
sibber
sibberā€¢15mo ago
oh well id think of a different name because this one is confusing anyway you don't you can just create a normal file
Itskillerluc
Itskillerlucā€¢15mo ago
in unity?
sibber
sibberā€¢15mo ago
yes
Itskillerluc
Itskillerlucā€¢15mo ago
wait what šŸ˜®
sibber
sibberā€¢15mo ago
unity c# is still c# just out of date and the unity api is weird but other than that
Itskillerluc
Itskillerlucā€¢15mo ago
well if there are good alternatives for unity i could use that but the others seem way harder and more annoying like ofc there is unreal but no way that im gonna code in C++ bruh the C# naming conventions suck, public fields have the same conventions as public classes, im just gonna get duplicates now
sibber
sibberā€¢15mo ago
you can used to it unreal c++ is a lot different from regular c++ from what ive heard but im not telling you not to use unity unity's fine
Itskillerluc
Itskillerlucā€¢15mo ago
just not having garbage collections scares me
sibber
sibberā€¢15mo ago
you can name fields the same as classes
Itskillerluc
Itskillerlucā€¢15mo ago
no you cant it doesnt work
sibber
sibberā€¢15mo ago
but unity's naming convention is different in regular apps we dont use public fields
Itskillerluc
Itskillerlucā€¢15mo ago
wdym you use all getters and setters?
sibber
sibberā€¢15mo ago
unity names all fields in camelCase anyway yes properties
Itskillerluc
Itskillerlucā€¢15mo ago
they dumb tho like if im gonan have a getter and a setter, then why do i not just make it public tf
MODiX
MODiXā€¢15mo ago
Cyberrex#8052
REPL Result: Success
class C
{
public Test Test;
}

class Test {}
class C
{
public Test Test;
}

class Test {}
Compile: 408.569ms | Execution: 39.195ms | React with āŒ to remove this embed.
Itskillerluc
Itskillerlucā€¢15mo ago
you can compile code
sibber
sibberā€¢15mo ago
see it works
Itskillerluc
Itskillerlucā€¢15mo ago
in discord???? oh
sibber
sibberā€¢15mo ago
its a bot
Itskillerluc
Itskillerlucā€¢15mo ago
its nested šŸ’€
sibber
sibberā€¢15mo ago
what is
Itskillerluc
Itskillerlucā€¢15mo ago
FOR GOOD REASONS THO the class
sibber
sibberā€¢15mo ago
because if at some point you decided to change the default getter and setter, you could
Itskillerluc
Itskillerlucā€¢15mo ago
fair
sibber
sibberā€¢15mo ago
but the main reason is to be consistent its not nested its defined below it
Itskillerluc
Itskillerlucā€¢15mo ago
mine is nested though
sibber
sibberā€¢15mo ago
oh i thought you were talking about the repl
Thinker
Thinkerā€¢15mo ago
Because you may want to have logic in the getter/setter
cap5lut
cap5lutā€¢15mo ago
getter and setters are a lot easier in c#
public class A {
public int Value { get; set; }
}
public class A {
public int Value { get; set; }
}
and u r done with having a getter and a setter, u can also have getters and initializers only { get; init; }, etc
Itskillerluc
Itskillerlucā€¢15mo ago
oohhhh ohhhhhhh thats cooool intializer? just =?
Thinker
Thinkerā€¢15mo ago
But Unity doesn't let you use them mmLul
cap5lut
cap5lutā€¢15mo ago
a setter that u can use only once no init in unity? D:
Itskillerluc
Itskillerlucā€¢15mo ago
oof
Thinker
Thinkerā€¢15mo ago
outdated language version
Itskillerluc
Itskillerlucā€¢15mo ago
idk my ide says i can do it and its like synched with unity
cap5lut
cap5lutā€¢15mo ago
but in the end if u would have to add functionality to the getter/setter it becomes a bit more bloaty, but still not as much as java:
public class A
{
private int _value;
public int Value
{
get => _value;
set
{
if (value > 255) throw new ArgumentException();
_value = value;
}
}
}
public class A
{
private int _value;
public int Value
{
get => _value;
set
{
if (value > 255) throw new ArgumentException();
_value = value;
}
}
}
but this way u dont have breaking changes in the API itself also regarding nested classes: they work differently in c# than nested inner classes in java btw., as it wouldnt have automatically a reference to the outer instance.
public class A {
public String name;
public class B {
String getOuterName() {
return A.this; // this part doesnt exist in c#
}
}
}
public class A {
public String name;
public class B {
String getOuterName() {
return A.this; // this part doesnt exist in c#
}
}
}
Itskillerluc
Itskillerlucā€¢15mo ago
lol
krazycay
krazycayā€¢15mo ago
yo question how can i detect when the console app is minimized
cap5lut
cap5lutā€¢15mo ago
open separate thread for that question. its totally unrelated to this
Itskillerluc
Itskillerlucā€¢15mo ago
bruh does C# also not have enhanced enums? nvm it does
Jimmacle
Jimmacleā€¢15mo ago
idk what an enhanced enum is
cap5lut
cap5lutā€¢15mo ago
to have it sorta like java u could use extension methods, but i think its sorta ugly
public enum MovementType { Sprinting, Walking, Sneaking }
public static class MovementTypeExtensions
{
public static float GetMovementSpeed(this MovementType type)
{
switch (type)
{
case MovementType.Sprinting: return 1.5f;
case MovementType.Walking: return 1.0f;
case MovementType.Sneaking: return 0.5f;
}
throw new Exception(); // dunno right now the best exception type to throw here
}
}
public enum MovementType { Sprinting, Walking, Sneaking }
public static class MovementTypeExtensions
{
public static float GetMovementSpeed(this MovementType type)
{
switch (type)
{
case MovementType.Sprinting: return 1.5f;
case MovementType.Walking: return 1.0f;
case MovementType.Sneaking: return 0.5f;
}
throw new Exception(); // dunno right now the best exception type to throw here
}
}
which u could then use via MovementKind.Sprinting.GetMovementSpeed(); but something like this would be more c# like i would say:
public enum MovementKind { Sprinting, Walking, Sneaking }
public readonly struct MovementType
{
public static readonly MovementType Sprinting = new MovementType(MovementKind.Sprinting, 1.5f);
// for the other types

public MovementKind Kind { get; }
public float Speed { get; }

private MovementType(MovementKind kind, float speed)
{
Kind = kind;
Speed = speed;
}
}
public enum MovementKind { Sprinting, Walking, Sneaking }
public readonly struct MovementType
{
public static readonly MovementType Sprinting = new MovementType(MovementKind.Sprinting, 1.5f);
// for the other types

public MovementKind Kind { get; }
public float Speed { get; }

private MovementType(MovementKind kind, float speed)
{
Kind = kind;
Speed = speed;
}
}
Thinker
Thinkerā€¢15mo ago
If you didn't notice, this is a post for a completely different question. Please open a new post in #help.
FusedQyou
FusedQyouā€¢15mo ago
Stuff like init is allowed but won't compile unless you add a sort of workaround, such as this:
using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
/// <summary>
/// Reserved to be used by the compiler for tracking metadata.
/// This class should not be used by developers in source code.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class IsExternalInit
{
}
}
using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
/// <summary>
/// Reserved to be used by the compiler for tracking metadata.
/// This class should not be used by developers in source code.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class IsExternalInit
{
}
}
Unity supports latest .NET Standard but stuff like init is not part of that, only .NET 6, 7 and 8
Accord
Accordā€¢15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.