6

In 2000, Scott Meyers argued that non-member functions improve encapsulation. In C++, a non-member function is a C-style global function:

http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197

If you subscribe to his theory, how would you implement this in C#?

If you don't subscribe to his theory, and wish to debate the topic, please do it outside of this post (I suggest her: Feel free the comment here with regard to the actual pattern: --- https://plus.google.com/105106301233937725736/posts/QvhKbB3y7F2 .)

This question is about how to best implement that pattern in C#. Acceptable answer describes a set of rules to use this pattern from C#

1
  • I was looking for scotts article and this q is the only place I found that at least refers to it. Any idea if it is still online somewhere? In any case: your link is broken :( Commented Sep 16, 2019 at 12:24

1 Answer 1

3

Use the following rules:

  1. For any non-static method of a class which a) does not access private fields directly and b) only calls public methods, move the method to a static helper class and turn it into an extension method.

  2. Any public static method can also be moved to a helper class.

By convention, a helper is a new static class with the same name as the original class but with the word Helper appended to it.

Example:

ORIGINAL CODE:

public class Foo
{
    int _intField;

    public void Method1()
    {
        doing something with _intField;
    }

    public void Method2()
    {
        Method1();
    }

    public static void Method3()
    {
        ....
    }

    private void Method4()
    {
        ....
    }

    public void Method5()
    {
        Method4();
    }
}

PROPOSED TRANSOFORMATION:

public class Foo
{
    int _intField;

    public void Method1()
    {
        doing something with _intField;
    }

    private void Method4()
    {
        ....
    }

    public void Method5()
    {
        Method4();
    }
}

public static class FooHelper
{
    public static void Method2(this Foo foo)
    {
        foo.Method1();
    }

    public static void Method3()
    {
        ....
    }
}
  • Method 1 cannot move because it's using a private field
  • Method 2 can move because it's not using a private field and it's calling a public method. It can be turned into an extension method.
  • Method 3 can be moved because it's a static public method
  • Method 4 cannot move because it's a private method
  • Method 5 cannot move because it's calling a private method.

5
  • I like the idea of using extension methods for this purpose - though the core point of Scott Meyer's article would work without extension methods, they make the usage much easier, and when you are going to refactor existing code accordingly, you do not have to change any calling code. I would probably name the helper class FooExtensions to make the purpose more expressive.
    – Doc Brown
    Commented Feb 13, 2015 at 7:18
  • Doc, the only reason I didn't call FooExtensions is because it contains methods that are not extensions, such as public static methods. The idea is that an extension is just a type of helper, but there are other types of helpers as well. (Thanks to Stephen for this suggestion) Commented Feb 13, 2015 at 7:35
  • 2
    Point taken. Well, I just tried this technique here on a real world project and moved an "Angle" method out of my "Point2D" class to a extension (or helper) class. It works smooth as long as you have pure C# code. But the class I changed was also referenced in a C++/CLI assembly - and guess what? It now does not find the extension method any more without changing the code. Of course, that's just a minor drawback, which won't occur in many other projects.
    – Doc Brown
    Commented Feb 13, 2015 at 7:50
  • I would use a namespace instead of a static class. See this answer for more: stackoverflow.com/questions/1434937/…
    – mdeforge
    Commented Dec 8, 2016 at 4:04
  • Stradigos, you can't just use a namespace in c#. There's no global functions like you do in C++ yet. You have to put static methods in a class. Of course you can wrap the class in a namespace, but it's not necessary to illustrate technique I'm describing. Commented Dec 10, 2016 at 1:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.