Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Why does C# have ref vs value types ....LOOK the same?

Discussion in 'Scripting' started by astracat111, Jun 8, 2018.

  1. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    719
    I never quite understood why C# has reference types look the same and almost be 'mixed in' with value types.

    A string is a reference type, right? Well why don't they just put a big ol * in the front of it or have it where you define it like "reftype string myString" or something?

    There are a few problems that I see cropping up in my code that I otherwise ignorantly in my newbishness believe is full proof. At the top of these common bugs I'm finding over the past year it's been mainly this problem that crops up again and again. There's no distinction like there is with C++ with pointers and values....sorry I'm not sure I'm saying that right I haven't programmed in C++ in a few years...

    Recently, I've had abilities in an ability list like this:

    List<Ability> abilityList = new List<Ability>();

    Then, I accidentally like a true idiot did like:

    string abilityName;

    And then

    abilityName = abilityList[x].Name;

    Now later on when I tried to 'reset' the value to "", I ended up changing the value in my database with the following:

    abilityName = "";

    If anyone newer to C# is reading this, you need to keep this in mind, what a reference type is and how it differs from a value type. It's an important distrinction to make.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    I'm not clear how this example you wrote was a problem.

    What did you expect to happen when you did:
    Code (csharp):
    1. abilityName = "";
    vs what actually happened?
     
    astracat111 likes this.
  3. jc_lvngstn

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508
    I think I get your confusion, you were expecting abilityName and abilityList[x].Name to both reference the same object on the heap. By setting abilityName = "", you were expecting abilityList[X].Name to be "' also, is that correct?

    If so, sorry, that's not gonna work, strings (and several other types) are reference types, but they are immutable for good reasons.

    But wouldn't you have the same issue in C++? Let's say you created your own type, called EmailMessage. It's a reference type. But when you copy that message, you want to send a copy/new instance of the message, instead of referencing the original.

    You'd essentially make it immutable, where saying NewEmail->Message = OldEmail->Message or something like that. and NewEmail's message would be a clone or copy of the old one. That's basically what strings are doing. It's still a reference type, but specifically coded to handle assignments like a value type.

    You would have to add some sort of keyword or attribute to the class itself, to let developers using it visually SEE that it is immutable. I'd go for that, rather than add some new keyword or symbol when I declare it, less clutter is better.

    But really, this is more of a design pattern right? It's a coding implementation and making it clear to the user, rather than a type issue.
     
    astracat111 likes this.
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,196
    @astracat111, that won't change the value of the string in the list. You're setting your abilityName pointer to point to a new (empty) string, that won't have any side-effects unless it's a ref parameter somewhere, like:

    Code (csharp):
    1. void Foo(ref string abilityName) {
    2.     abilityName = "";
    3. }
     
    astracat111 likes this.
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    You've discovered the point of the "Reference Type" system. It's purposely meant to blur the different between pointers and normal (automatic) variables. If you don't know pointers, then a syntax emphasizing when you are or aren't using one is just going to confuse you.

    That's why structs have a useless [new] in the constructor. If you know [new] means a heap allocation, it's a purposely misleading lie. But if you don't know, you simply think "I can type the same thing to make a class or struct var. Yay!"
     
    astracat111 likes this.