Debugging Multi-Language Programs

A very cool feature of .NET is the multi-language capability. I still hear discussions about which language is better, but I just don't think it matters that much any more. I don't know anyone (or any company) developing one application with language heterogeneity—for example, VB .NET and C#—in the same application, but you can do it. I have to be careful here because I haven't written an enterprise application that tests this presumption, but I have implemented Visual Basic .NET classes that inherit from C# classes and vice versa and traced through the source code in the debugger. Everything seemed to work fine. I have included a sample application in Listing 17.12 for you to play with; it is worth the “cool factor” alone.

TIP

A language must comply with the Common Language Specification to participate in cross-language interoperability.


Listing 17.12. A Multi-Language C# and Visual Basic .NET Demonstration
1:  // C# base class
2:  namespace TrafficControls
3:  {
4:    using System.Drawing;
5:    using System.Diagnostics;
6:
7:    public abstract class AbstractTrafficLight
8:    {
9:      public abstract void Draw(Graphics graphics);
10:
11:     public abstract class AbstractLamp
12:     {
13:       private Color color;
14:
15:       public AbstractLamp(Color color)
16:       { this.color = color; }
17:
18:       public Color Color
19:       {
20:         get{ return color; }
21:         set{ SetColor(value); }
22:       }
23:
24:       protected virtual void SetColor(Color value)
25:       {
26:         Debug.Assert(value == Color.Red
27:           || value == Color.Green
28:           || value == Color.Yellow);
29:         color = value;
30:       }
31:
32:       public abstract void Draw(Graphics graphics, _
33:         Rectangle r, bool isOn);
34:     }
35:   }
36: }
37: // Visual Basic .NET subclass
38: Imports System.Drawing
39: Imports System.Windows.Forms
40: Imports System.Drawing.Drawing2D
41:
42: Public Class TrafficLight
43:   Inherits TrafficControls.AbstractTrafficLight
44:
45:   Public Enum LightState
46:     Green
47:     Yellow
48:     Red
49:     Off
50:   End Enum
51:
52:   Private FState As LightState = State.Green
53:
54:   Public Property State() As LightState
55:   Get
56:     Return FState
57:   End Get
58:   Set(ByVal Value As LightState)
59:     FState = Value
60:   End Set
61:   End Property
62:
63:   Public Sub [Next]()
64:     FState = (FState + 1) Mod LightState.Off
65:     Debug.WriteLine(FState.ToString())
66:   End Sub
67:
68:   Private Lamps() As Lamp = New Lamp() _
69:     {New Lamp(Color.Green), New Lamp(Color.Yellow), _
70:      New Lamp(Color.Red)}
71:
72:   Public Overloads Overrides Sub Draw(ByVal g As Graphics)
73:
74:     g.FillRectangle(Brushes.Brown, New Rectangle(0, 0, 50, 160))
75:
76:     Dim I As Integer
77:     For I = 0 To Lamps.GetUpperBound(0)
78:       Lamps(I).Draw(g, New Rectangle(5, _
79:         ((2 - I) * 50) + 3, 40, 45), I = State)
80:     Next
81:     Next
82:   End Sub
83:
84:   Public Class Lamp
85:     Inherits TrafficControls.AbstractTrafficLight.AbstractLamp
86:
87:     Public Sub New(ByVal Color As Color)
88:       MyBase.New(Color)
89:     End Sub
90:
91:     Private Function GetBrush(ByVal isOn As Boolean) As Brush
92:       If (isOn) Then
93:         Return New SolidBrush(Color)
94:       Else
95:         Return New HatchBrush( _
96:           HatchStyle.DashedHorizontal, Color.Gray)
97:       End If
98:     End Function
99:
100:    Public Overloads Overrides Sub Draw(ByVal g As Graphics, _
101:      ByVal r As Rectangle, ByVal isOn As Boolean)
102:
103:      g.FillEllipse(GetBrush(isOn), r)
104:
105:    End Sub
106:
107:  End Class
108:
109: End Class

The 109 lines of sample code implement a rudimentary traffic signal with red, yellow, and green lamps. You can run MultiLanguageDemo.sln to see the lamp change colors at regular intervals. The code draws three colored circles inside a rectangle and is itself not very exciting. What is exciting is that these two files are in different assemblies (but in the same solution), and the VB .NET TrafficLight class inherits from the C# AbstractTrafficLight class. I made the code intentionally complex to test the multi-language capability and, in part, because I thought the solution made sense.

AbstractTrafficLight defines the concept of a traffic control comprised of illuminated (colored) lights. Because the light controls which lamps are on and which are off, I also implemented a nested AbstractLamp class. The VB .NET code mirrors the C# code by defining a TrafficLight class and a nested Lamp class. TrafficLight inherits from AbstractTrafficLight, and Lamp inherits from AbstractLamp. The code works perfectly, and debugging in and out of VB .NET and C# works flawlessly in Visual Studio .NET. I can easily use all the techniques we have discussed. (For example, line 65 demonstrates a Debug.WriteLine statement.)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.20.125