What does the ref keyword actually do in C#?

Поделиться
HTML-код
  • Опубликовано: 8 сен 2024

Комментарии • 69

  • @minhgiangho1410
    @minhgiangho1410 3 года назад +71

    public interface ISerivce{}
    public interface ISerivce{}
    public interface ISerivce{}
    Please make a video on this topic

    • @nanvlad
      @nanvlad 3 года назад +8

      it's called type variance - simple to explain but hard to understand and use in your practice

    • @tobyjacobs1310
      @tobyjacobs1310 3 года назад +1

      +1 for a video on these.... They're really useful if you can pick up the times you should be using them, and such a pain to get those times right...

    • @tamaratiny
      @tamaratiny 3 года назад +2

      That wouldn't compile

    • @angelmunoz6332
      @angelmunoz6332 Год назад

      @@tamaratiny 😂😂😂

  • @hrrrrustic
    @hrrrrustic 3 года назад +23

    Also It could be great to mention "in" keyword for structs

  • @chimaokoli4943
    @chimaokoli4943 3 года назад +4

    Watching Nick Chapsas video > Reading Docs

  • @PaulBurg
    @PaulBurg 2 года назад +7

    I got to this video after researching unity to help my niece out, and I have to say this just makes me appreciate C++ so much more. It manages to be much less verbose but simultaneously much more clear about what is going on.

  • @alphaprimal1669
    @alphaprimal1669 3 года назад +30

    Me here getting Pointers/Refs PTSD from my cpp era

    • @igorthelight
      @igorthelight 3 года назад +5

      Both pointers and refs are available in C# :-)

    • @alphaprimal1669
      @alphaprimal1669 3 года назад +8

      well it's not called c++++ for no reason lol

  • @valerii-barabanov-vvb
    @valerii-barabanov-vvb 2 года назад +3

    It's worth mentioning that you can't return a List element by reference.

  • @Tolg
    @Tolg 2 года назад +2

    Thank you so much! Learned something today. Didn’t know you could return ref values from a function!

  • @spacerecluse
    @spacerecluse 3 года назад +2

    in : arguments cannot be changed by the called method
    ref : arguments can be changed
    out : arguments must be changed by the caller and these changes are tracked in the calling context

  • @ivaniliev93
    @ivaniliev93 2 года назад

    readonly ref = const in C++, now we need a readonly method (which doesn't change the data members of the class) which returns a readonly ref (a reference which we can only read but not modify). I completely love these performance improvements :D

  • @voliker
    @voliker 3 года назад +9

    420 69 in the struct example :)
    I love you nick

  • @DarthJane
    @DarthJane 3 года назад +1

    Another interesting case is if you have a class "class Point { public int X; public int Y; }" and then do something like:
    Point p = new Point { X = 5, Y = 10 };
    ref int x = ref p.X;
    x = 20;
    int xb = x;
    xb = 25;
    where in the end p.X is 20 and p.Y is 10, as xb creates a copy from x which is then overridden but the assignment to xb never touches p.X

  • @TomBauto
    @TomBauto 3 года назад

    Thanks Nick good content! I liked the fact you made a correction/clarification in the end, very professional and time saver.

  • @donsk324
    @donsk324 Год назад

    I love your random values.

  • @art3a
    @art3a 3 года назад +1

    Thanks for a nice video, as always! Next time, please, add a reference to a video you are talking about, would be great!

  • @mohamedsalman3205
    @mohamedsalman3205 3 года назад +4

    What I understood is, Say the main variable is A and the parameter is B,
    Reference type without ref: Creates an object on the heap and assigns that object's location to A. So when calling the method, it is actually passing the object it self. So what happens is, It creates another allocation in the stack named B which has the pointer to the same object. Now A and B both are pointing the same object. Now when you say B equals new object, it creates a new object in the heap and updates B's location to point to the new object. Now A is pointing to the first object and B is pointing to newly created one. That's why A is not affected.
    Reference type with ref: Creates an object on the heap and assigns that object's location to A. When calling the method, it is actually passing the a reference to A or a pointer to A. So what happens is, It creates another allocation in the stack named B which has the pointer to A. It is like saying A= new object and B = A. Now when you say B equals new object, it creates a new object in the heap and since B is just a pointer to A it updates A's location to point to the new object. That's why A is affected.

    • @DarthJane
      @DarthJane 3 года назад +1

      There is no "reference type without ref".
      You have a class, which is allocated on the heap, and you have a reference to it to access it. When passed to a method the reference is copied, but the data stays in place.
      You have a struct, which lives either inside a class, or on the stack. When passing it to a method the whole struct is copied onto the stack.
      Then you have a ref struct, the data is allocated once on the stack, and you're also given a reference to it like with a class. When passed to a method again the reference is copied, but the data again just stays in place.
      As objects on the stack are not controlled by the garbage collector accessing members of a ref struct is much more efficient than accessing members of a class.
      Then there is "passing by ref" where you have something like "myfunc(ref mytype x)", in which case a new reference is created for the method. That reference is either a reference to a reference of a class-object, or a reference to a struct, or just the copy of a reference to a ref struct. For the first case if you use new() the old reference is overridden with the reference to the new object. Any other references to the old object remain unchainged, and will still point to the old object. In the case of the latter two the actual data will be overridden.

  • @dimitrishadrin
    @dimitrishadrin 3 года назад +1

    One interesting point to mention in my opinion is that ref and out keywords with value type do not lead to any boxing/unboxing and it is pretty efficient in that case.

    • @nickchapsas
      @nickchapsas  3 года назад +1

      It’s not about just boxing but about the cost of passing a value type by reference too, which is very cheap

    • @dimitrishadrin
      @dimitrishadrin 3 года назад +1

      @@nickchapsas this is exactly what I meant.

    • @user-cm8bn7vt9y
      @user-cm8bn7vt9y 3 года назад

      @Nick Chapsas Hi, can you please share your settings on code visual look, what is this theme, or is it custom? Font size, font family, colors...

  • @rohanamada7136
    @rohanamada7136 3 года назад

    These videos are indeed helpful. tnx

  • @dyland30
    @dyland30 3 года назад +1

    Great content as always!

  • @user-mb1qe8je2v
    @user-mb1qe8je2v 3 месяца назад

    thanks buddy

  • @OnsGod
    @OnsGod 3 года назад +4

    69, 420 nice example bro

    • @42069_
      @42069_ 3 года назад

      Lool

  • @ZeroSleap
    @ZeroSleap 2 года назад

    Huh never thought of this,but thats when you'd want to return a value,or just have a void function.When you pass by reference,you can ignore returning and put void.But if it's passed by value,you'd have to return the renewed value.I see.

  • @a_i_k_0_n
    @a_i_k_0_n 3 года назад

    Hi, thanks for your videos. Are you can to make some "off top" video? About chair, monitor rack, table? We are (programmers) spent a lot of time with this :) I'm interesting with your opinion about this topic. Thanks

  • @woodbyte
    @woodbyte 3 года назад +2

    Nice

  • @RixtronixLAB
    @RixtronixLAB 3 года назад

    Cool video, thanks :)

  • @carl-marvin
    @carl-marvin 2 года назад

    I still don't know what the ref keyword in C# actually does. How is it realised? Is it just a stack pointer?

  • @Omego2K
    @Omego2K 3 года назад

    Ha I see what you did there. Thumbs up for that for sure

  • @raminquliyev2268
    @raminquliyev2268 3 года назад +1

    Okay Nick, Can we say that ref is same with pointer in c, c++ ?

    • @mk72v2oq
      @mk72v2oq 3 года назад +2

      Not really, ref is like C++ reference.
      C# has actual pointers available in unsafe context.

  • @necroyzablo
    @necroyzablo 3 года назад

    It is a pity that there were no performance tests for ref structures.

  • @benjaminclehmann
    @benjaminclehmann 3 года назад

    Always thought that the confusing part was mixing the "ref means reference" and the "ref means stack-allocated", is there any logic behind why they both use the same keyword?

    • @DarthJane
      @DarthJane 3 года назад

      It's not so much a mix than you think.
      As C# is managed the actual data can usually be moved freely by the garbage collector and the reference to that needs to be updated when that happens. This is what happens when you have a class. The reference is a small lightweight object that points to your actual data, which is why classes are regarded as "slow".
      Now if you take structs if you use them inside a function they are allocated on the stack, if they are part of a class the data of the instance also stores the struct (which is on the heap). Now if you do 'var mystruct = something.mystructinstance' that struct is copied onto the stack for you to use, but chaning it will not also change the struct in the original something object. Now if you want a reference to the data which is in the something object you have to use 'ref var mystruct = ref something.mystructinstance'. The issue is that this reference just isn't as fast as accessing the struct directly.
      Now for C# to be as fast as most other languages here there's the 'ref struct'. As it can only be allocated on the stack so the whole garbage collector stuff which usually runs in the background isn't active. In essence if you're using a ref struct it's allocated on the stack and you're returned a direct pointer to the object which has way faster access than a class.
      If you would try to allocate a 'ref struct' on the heap it would essentially be nothing else but a class (ignoring stuff like inheritance which structs in C# do not have to keep them as light as possible).

    • @benjaminclehmann
      @benjaminclehmann 3 года назад

      @@DarthJane You misunderstand me. I know what the ref keyword does in both situations. I don't understand why we use the same keyword for very different things.
      Especially when constraining something to be stack allocated doesn't have anything to do with references, which is the namesake of the keyword.

  • @weluvmusicz
    @weluvmusicz 3 года назад +2

    Why can't we mix ref with async?

    • @DarthJane
      @DarthJane 3 года назад +1

      async behind the scenes creates a state machine to store its data, so the "ref" you have will go out of scope.

    • @weluvmusicz
      @weluvmusicz 3 года назад +1

      @@DarthJane Wrong: Essentially, a ref struct is not allowed to be a field of a class. Why does this matter in an async context? Because the compiler converts an async method to a class, and all local variables are turned into a field, essentially.

    • @DarthJane
      @DarthJane 3 года назад +2

      @@weluvmusicz Depends on how you look at it. ref structs can still be used inside ref classes, but the point is that the scope of an async operation might shift, or even be on another whole thread which is why a ref class is not able to be used. So from that point of view your and my explanation are both true.

  • @vertxxyz
    @vertxxyz 3 года назад

    Is there a reason you use the VS colour scheme? To me it's kinda appalling that it doesn't have different highlighting for structs.

  • @siratthebox
    @siratthebox Год назад

    Hello

  • @42069_
    @42069_ 3 года назад

    7:48 yeah this is so random

  • @olmanmora21
    @olmanmora21 2 года назад

    ref the way you can make an struct behave as a class

  • @pramod.kulkarni9607
    @pramod.kulkarni9607 Год назад

    Great video...

  • @meirkr
    @meirkr 2 года назад

    Video paused. Value shall be only "hello"

  • @mascotto
    @mascotto 3 года назад +1

    Its a basic C value and pointer..

    • @sodiboo
      @sodiboo 3 года назад

      Not quite. C# also has pointers which is just like "basic C values and pointers", but not everyone knows C, and C# provides a similar, safer way of passing arguments by reference

    • @mascotto
      @mascotto 3 года назад

      @@sodiboo In that case while I was watching the video, yes. Who works with C, value and pointer, masters almost everything :)
      In embedded systems, its always a rule to pass structs as pointers due low footprint and limited stack. But pointers are "wild" hehehehe

    • @protox4
      @protox4 3 года назад +3

      It's more like C++'s `&` reference

    • @mascotto
      @mascotto 3 года назад

      @@protox4 Love and hate for the & and *. What else language can navigate thru structures with Ptr++ like a charm?

    • @igorthelight
      @igorthelight 3 года назад

      @@mascotto C, C++ and C# :-)

  • @AndrewJonkers
    @AndrewJonkers 3 года назад

    ref. The absolute worst feature of C#. Should be removed.

    • @AEF23C20
      @AEF23C20 2 года назад

      use sharp without refs
      thats all)

  • @tobyjacobs1310
    @tobyjacobs1310 3 года назад

    Ok, this one is an unusual use that you might find interesting: Improving performance when accessing members of value tuples stored in arrays.
    Given:
    class Foo
    {
    (int, int, string, string, CustomObject) _Buffer;
    ...
    public CustomObject ReadObjectAtSlow(int index) {
    (_,_,_,_,var res) = _Buffer[index];
    return res;
    }
    public CustomObject ReadObjectAtFast(int index) {
    // This should profile about 20% faster for big N scenarios
    ref var reftuple = ref _Buffer[index];
    return reftuple.Item5;
    }
    }