Code Focused

Conflicts in C# and Visual Basic

Case matters when moving from one language to another and, often, variable naming conflicts can be as simple as that.

The very first programming language I used back in high school did not permit variable names longer than two characters. Visual Basic and C# have more reasonable limits, but naming conflicts with identifiers can still occur. Each language includes a special syntax that deals with identifiers that conflict with internal keywords.

In C#, you can attach an at sign to the start of an identifier, if needed:

for (int @for = 1; @for <= 5; @for++)

In Visual Basic, this name avoidance system uses a set of square brackets around the conflicting identifier:

For [for] As Integer = 1 To 5

In that Visual Basic example, it doesn't matter if the poorly named variable starts with a lowercase or uppercase letter. Both "for" and "For" conflict with the loop statement keyword, and must be qualified with brackets. But that's not true of C#. Because that language is case-sensitive, changing the case of the first letter of the strange identifier also resolves the problem:

for (int For = 1; For <= 5; For++)

C#'s case-sensitive benefits normally stay within the language. But it's possible to create a C# class library that Visual Basic cannot use directly, all thanks to differences in how each language resolves case issues. Consider this simple C# type:

public class Class1
{
  public int field1 = 5;
  public int Field1 = 10;
}

Because field1 and Field1 vary by the case of their first letters, this class works just fine in C#, although I would seriously question your future employment prospects. However, if you reference this class from a Visual Basic project, and attempt to access the field1 and Field1 members of a Class1 instance, you receive the following compile-time error: "'field1' is ambiguous because multiple kinds of members with this name exist in class."

If you need to access such ambiguous members from a Visual Basic project, you can use the power of .NET Reflection to work with these elements indirectly. The following code uses the Reflection'FieldInfo type to retrieve the default value of each member from the referenced C# class:

Dim targetInstance As New CSharpLibrary.Class1
Dim strangeType As Type = GetType(CSharpLibrary.Class1)
Dim lowercaseField As Reflection.FieldInfo =
  strangeType.GetField("field1")
Dim uppercaseField As Reflection.FieldInfo =
  strangeType.GetField("Field1")
Dim lowercaseValue As Integer =
  lowercaseField.GetValue(targetInstance)
Dim uppercaseValue As Integer =
  uppercaseField.GetValue(targetInstance)

The better solution, of course, is to avoid features that complicate cross-language development. But in the fun-loving world of .NET programming, you need to prepare for such issues, just in "case."

About the Author

Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development -- Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 -- are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

comments powered by Disqus

Featured

Subscribe on YouTube