-4

UPDATE: I do understand basic C# concepts, I must be explaining this poorly...

Stream = Reference Type, pointer to location in memory that holds the actual object

Parameter = Passed as the type of the object (Stream is still a Reference type, and int would be a value type)

Ref Parameter = Allows manipulation of parameter that will persist outside the method block

In looking at this some more and running some tests, it appears the answer depends on what I am trying to do. This question helped me distinguish what I was trying to do for my tests: How can I get an extension method to change the original object?

For most of my helpers, extension methods work great since they can return the answer and I don't need to replace the original object. For other helpers, I am better off using a method with a ref parameter so I can update the original object. I could make the extension mimic the ref parameter by returning a new object, but doing so is a memory penalty given the extra allocation.


Contemplating some of the helper classes I have created, I was wondering if there are any functional or performance differences between extensions and methods with a ref parameter. Especially with something large like streams, my first though was that passing the stream by ref would be more performant when running different validations on said stream, but extension methods also have a reference like signature in that they are static.

static bool IsValidSize(this Stream stream, long size)

bool IsValidSize(ref Stream stream, long size)

So are there any functional or performance differences between these two method signatures?

Community
  • 1
  • 1
Dan
  • 1,101
  • 1
  • 9
  • 30
  • But you would not pass the steam to a steam extension method. I think you need to visit the documentation on each. – paparazzo Jun 07 '16 at 19:34
  • 2
    This question doesn't make any sense; I think you don't understand what a ref parameter is. – Eric Lippert Jun 07 '16 at 21:05
  • "Ref Parameter = Allows manipulation of parameter that will persist outside the method block" - this is actually what you can do with any reference type object **with or without a `ref` keyword**. Your description is the functionality you gain if the parameter is a value type. If it's a reference type, it's going to be a reference to a reference of an object, which is subtler than what your question is asking about. – Frank Bryce Jun 09 '16 at 15:28

3 Answers3

4

In this example:

bool IsValidSize(ref Stream stream, long size)

You wouldn't pass stream by ref unless you intended for IsValidSize to modify the stream used by the caller.

Regarding extension methods, their benefit is that you don't up with lots of "helper" classes that you have to use. Instead the methods appear to be part of the class they extend. That way you can say:

stream.IsValidSize(size);

rather than:

StreamHelper.IsValidSize(stream, size);

When you say that:

passing the stream by ref would be more performant

I think you not quite understanding the difference between value and reference types in C#. stream is a reference type, so when it is passed to another function a copy if not made of the stream. Instead the caller and the callee both point (ie reference) the same stream instance. This means that passing around reference types is very fast and lightweight. Value types are different as a copy is made whenever they are assigned or passed into functions.

Sean
  • 60,939
  • 11
  • 97
  • 136
  • Ok, for this example passing by ref is silly, but lets say the method was called "TrimEndBytes", would passing the stream by ref be more efficient than an extension that did the samething? I understand that reference types get passed by value which is just the value of the location of the object (https://msdn.microsoft.com/en-us/library/s6938f28.aspx). Functionally it appears there is no difference between these two signatures, I just wanted to find out if anyone knew of a difference since they both do the samething with different implementations. – Dan Jun 07 '16 at 19:53
  • 2
    I don't think you understand the passing by ref is not about reference type or value type. Refer to the documentation https://msdn.microsoft.com/en-us/library/14akc2c7.aspx – paparazzo Jun 07 '16 at 20:14
1

What is the difference between an extension method and a method with a ref parameter?

In how you call it, the difference is like this

public static void ConcatExtension(this string s, string strToAppend) {
    s = s + strToAppend;
}
// ... sometime later
string str = "this is ";
str.ConcatExtension("my string");

Which is different than a static method with a ref parameter

public static void ConcatStatic(ref string s, string strToAppend) {
    s = s + strToAppend;
}
// ... sometime later
string str = "this is ";
ConcatStatic(str, "my string");

In terms of the functionality, it's the same in this example. However, with a ref parameter, you can change what it references whereas with an extension method you cannot change what the this parameter is pointing to.

Take this example.

public static void StringBecomesFoo(ref string s) {
    s = "Foo";
}

// ...
var myStr = "something";
Console.WriteLine(myStr);  // outputs "something"
StringBecomesFoo(ref myStr);
Console.WriteLine(myStr);  // outputs "Foo"

This is not possible simply by substituting ref with this. So this is another distinction.

Frank Bryce
  • 8,076
  • 4
  • 38
  • 56
0

An extension method allows you to add a method to a class that already exists without having to have access to the source code.

Passing by reference and extension methods are not related.

T. Holland
  • 89
  • 3
  • 11