Post

Inheritance vs. Partial (VB vs. C#)

In my previous post regarding trying to use partial as a mechanism to extend existing functionality in a base user control, someone asked: “Does VB work differently or are you just assuming? Using the same namespace across 2 different assemblies (even) works perfectly fine?”

Let’s answer the first question. It does appear that VB works differently than say, which in regard to this question I am assuming he is referring to, C#. This is based on testing and, as such, is limited to the scope of my testing. If I am incorrect in this, please let me know and provide specific example code to demonstrate such.

In this example, if I were to add the following class to a C# Windows Forms project…

1
2
3
4
5
6
7
8
9
10
11
12
13
namespace System.Windows.Forms
{
  partial class TextBox
  {
    private string text;

    public string Text
    {
      get { return text; }
      set { text = value; }
    }
  }
}

Then add a text box control to the form… build… notice errors. Of course, the errors are to be expected. This issue, the one that I didn’t point out for other reasons in my previous post, is that partial classes don’t work across assemblies.

On another note, I can’t believe that people would find the following code a good idea, even if the C# compiler does allow it…

1
2
3
4
5
6
7
8
9
10
11
12
13
namespace System.Windows.Forms
{
  class SomeCheesyTextBox: System.Windows.Forms.TextBox
  {
    private string text;

    public string MoreText
    {
      get { return text; }
      set { text = value; }
    }
  }
}

So now you’ve created a new control that exists within the System.Windows.Forms namespace… another developer coming along won’t know where to look for a bug if it exists in this control and might even go so far as contacting Microsoft regarding the offending issue… wait several days only to find out that that control isn’t actually something Microsoft put together.

As for differences between C# and VB, yes, there is a difference… but not in the way you’d think. VB allows you to specify (by default) a “global” namespace (called a “Root namespace”) for your application within the project properties. If this has a value, then you will experience the behaviors that I described. If you remove this (select the text, delete and leave it blank), then it will work in the same manner, with the same restrictions as C#. Meaning the following code would work just like the C# counterpart I show above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Namespace System.Windows.Forms

  Class SomeCheesyTextBox
    Inherits System.Windows.Forms.TextBox

    Private m_text As String

    Public MoreText As String
      Get 
        Return m_text
      End Get
      Set(Byval value As String)
        m_text = value
      End Set
    End Property

End Class

End Namespace

Now be aware that C# offers a similar feature, but it’s called a “Default namespace” and works a bit differently than VB. In C#, this option is used to add the namespace you entered within the code spit (code generation within Visual Studio).

Again, the same issues arise, no matter what language you are utilizing in trying to maintain the above code. I would also recommend, in regards to Windows Forms application development, to utilize the “global” namespace setting (the default behavior) in the Windows Forms project. If you want to create your own reusable library that you could share across projects, create class/component assemblies and remove the “global” namespace setting (labeled as “Root namespace” in My Project) and utilize the Namespace/End Namespace mechanism throughout your code. And yes, to be clear, you can span your code across multiple assemblies and still keep them organized within a single namespace hierarchy.

This post is licensed under CC BY 4.0 by the author.