locked
ref with class object as parameter RRS feed

  • General discussion

  • In my current project i have seen a use of ref keyword with class object for e.g.

    Class Myclass{}

    Class Myclass2

    {

    void fun(ref myclass obj)

    {}

    }

    Please elaborate about this, what is the need of ref keyword in this. 

    • Moved by CoolDadTxModerator Tuesday, August 14, 2012 1:45 PM Language related (From:Visual C# General)
    Tuesday, August 14, 2012 10:09 AM

All replies

  • basically it is used to pass an object by reference and not by value.So when you make any changes in the object inside the method body it will be reflected to actual variable we are passing in the parameter

    below is good link for deep learning

    http://msdn.microsoft.com/en-us/library/14akc2c7.aspx

    http://www.codeproject.com/Articles/42383/Ref-Keyword-for-Reference-Types


    Want to add MVP with my name.

    Tuesday, August 14, 2012 10:12 AM
  • Since class is a ref type it generally makes little sense to pass a class using the ref parameter because it already is behaving correctly.  Generally you only use ref with a value type but there are exceptions.  The most likely case where you'll use a ref with a reference type is if your method needs to change the instance assigned to the argument that you're passing in.  To be honest this should be rare.  In most cases it is better to return the new instances as the return value of the method rather than by modifying an argument.  If you have more data than can be returned by the reference type then you generally create a new type. 

    A special case exists if your function will always return a new instance of a type.  In this case you could also use ref but ref requires that the caller pass an initialized argument in just to get one back and that is bad design.  Therefore you'll morely likely see out used with ref types.  This is most common with TryParse methods.

    So, in summary, rarely will you use ref with a reference type.  In general you'll either use the return type to get an instance back or you'll use the out modifier instead.  But it is supported in the rare cases were you need to do so.

    Michael Taylor - 8/14/2012
    http://msmvps.com/blogs/p3net

    Tuesday, August 14, 2012 1:45 PM
    Moderator
  • Since class is a ref type it generally makes little sense to pass a class using the ref parameter because it already is behaving correctly.  Generally you only use ref with a value type but there are exceptions.  The most likely case where you'll use a ref with a reference type is if your method needs to change the instance assigned to the argument that you're passing in.  To be honest this should be rare.  In most cases it is better to return the new instances as the return value of the method rather than by modifying an argument.  If you have more data than can be returned by the reference type then you generally create a new type. 

    A special case exists if your function will always return a new instance of a type.  In this case you could also use ref but ref requires that the caller pass an initialized argument in just to get one back and that is bad design.  Therefore you'll morely likely see out used with ref types.  This is most common with TryParse methods.

    So, in summary, rarely will you use ref with a reference type.  In general you'll either use the return type to get an instance back or you'll use the out modifier instead.  But it is supported in the rare cases were you need to do so.

    I wouldn't say it doesn't make sense to use 'ref' on a class.  It's certainly not commonly used, but it makes perfect sense.

    "The most likely case where you'll use a ref with a reference type is if your method needs to change the instance assigned to the argument that you're passing in."

    Well, really, that's the only case.  The reason you pass a parameter by value, and not by reference, is so that you can modify the variable.  In the case of classes (reference types) this means modifying the reference (which object the variable refers to) rather than the object that is referenced.

    "Therefore you'll morely likely see out used with ref types."

    It's worth noting that 'out' and 'ref' are basically the same thing.  'ref' ensures that the parameter is initialized, out doesn't, but other than that they will both compile into the same thing.  It's sometimes easiest to think of them both as the same "feature" even if their standard uses cases are entirely different.

    Tuesday, August 14, 2012 2:46 PM
  • The case I mentioned isn't the only case.  You are ignoring P/Invoke and COM calls where you often have to use ref even though the underlying instance may never change.  It is strictly a signature need.  COM calls often need ref.

    out and ref are not the same as far as the language is concerned.  It is irrelevant how they compile down.  This won't compile:

    MyClass cls;
    SomeMethod(ref cls);

    But this will:

    MyClass cls;
    SomeMethod(out cls);

    Even in the method they work differently.  This won't compile:

    void SomeMethod ( out MyClass cls )
    { }

    But this will:

    void SomeMethod ( ref MyClass cls )
    { }

    They do similar things but they are designed for different purposes.  ref is an in/out parameter.  out is a true out parameter.  C# is one of the few languages that truly supports out parameters.  In my experience it is dangerous to even try to treat them as similar because they work differently, have different design requirements and serve different purposes.  In the cases I've seen people treat them as the same they almost always use ref even though out is more appropriate.

    Michael Taylor - 8/14/2012
    http://msmvps.com/blogs/p3net

    Tuesday, August 14, 2012 3:00 PM
    Moderator
  • out and ref are not the same as far as the language is concerned.  It is irrelevant how they compile down.  This won't compile:


    MyClass cls;
    SomeMethod(ref cls);

    But this will:

    MyClass cls;
    SomeMethod(out cls);

    Even in the method they work differently.  This won't compile:

    void SomeMethod ( out MyClass cls )
    { }

    But this will:

    void SomeMethod ( ref MyClass cls )
    { }

    They do similar things but they are designed for different purposes.  ref is an in/out parameter.  out is a true out parameter.  C# is one of the few languages that truly supports out parameters.  In my experience it is dangerous to even try to treat them as similar because they work differently, have different design requirements and serve different purposes.  In the cases I've seen people treat them as the same they almost always use ref even though out is more appropriate.

    I said they were the same other than for the compile time check as to whether or not the variable is initialized.  Showing a code snippet that is dependent on that change isn't disputing the assertion.

    I also did say that they are used for entirely different purposes, and I agree it is wrong when people use 'ref' when they really intended it to be an out only parameter, that said, it should be thought of as two different ways of accessing the same underlying functionality, that of a pass-by-reference parameter.

    Tuesday, August 14, 2012 3:20 PM
  • They are not the same.  Thinking that way is wrong.  They are about as similar as a reference type vs a pointer as a parameter or covariance vs contravariance or an interface vs abstract class.  They are related but not the same.  If you are interested in the theory around having 3 different parameter types (in, in/out, out) in languages then pick up any good compiler book.  But at this point I'm just rambling on about language rules so I'll stop boring you with language design.
    Tuesday, August 14, 2012 4:05 PM
    Moderator
  • They are not the same.  Thinking that way is wrong.  They are about as similar as a reference type vs a pointer as a parameter or covariance vs contravariance or an interface vs abstract class.  They are related but not the same.  If you are interested in the theory around having 3 different parameter types (in, in/out, out) in languages then pick up any good compiler book.  But at this point I'm just rambling on about language rules so I'll stop boring you with language design.

    http://blogs.msdn.com/b/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx

    "'out' and 'ref' are actually exactly the same behind the scenes. The CLR only supports 'ref'; 'out' is just 'ref' where the compiler enforces slightly different rules regarding when the variable in question is known to have been definitely assigned. That's why it is illegal to make method overloads that differ solely in out/ref-ness; the CLR cannot tell them apart! Therefore the rules for type safety for out have to be the same as for ref."

    Tuesday, August 14, 2012 4:31 PM