2

I'm having difficulty calling a function from a C# Class in a similar way that I call a function from a VB.NET Module.

I have a C# class General.cs

  using System;

  namespace XYZ.Classes
     {
     public static class General
     {
         //Object Null to Empty Function
         public static string NullToEmpty(object obj)
         {
             var returnString = "";
             if (obj != null)
             {
                 returnString = obj.ToString();
             }
             return returnString;
         }

     }
  }

This type of function can be called in VB.NET from anywhere in the project without declaring the module or prefixing the call - just using

  dim x as String = NullToEmpty(obj) - VB.NET

  var x = NullToEmpty(obj) - C#

From my googling, it seems a public static class with public static methods may be able to accomplish this in c#.

C# Example:

class foo.cs

  namespace XYZ.Classes
  {
      public class Foo
      {

          public string doFoo()
          {
               var obj = null;
               var foolish = NullToEmpty(obj);
               return foolish;
          }
       }
   }

The function shows up in intellisense (using ReSharper) - but it's not valid(red), so something is not referenced correctly - I'm just guessing...

The point is being able to simply use common 'User Defined' utility functions for null trapping, formatting, etc... - so as not to have to wrap all kinds of stuff in ugly C# code like this:

  obj.FooField = dr["Foo"] == null ? "" : dr["Foo"];

Would prefer:

  obj.FooField = NullToEmpty(dr["Foo"]);

This becomes even more useful for DateTime applications:

  obj.ActivityStartDate = dr["ActivityStartDate"] == null ? "" : Convert.ToDateTime(dr["ActivityStartDate"]).ToString("yyyy-MM-dd HH:mm:ss");

vs:

  obj.ActivityStartDate = GetDate(dr["ActivityStartDate"]);

Or Integer Conversion:

  cmd.Parameters["@BirthdayDay"].Value = String.IsNullOrEmpty(obj.BirthdayDay) ? 01 : Convert.ToInt32(obj.BirthdayDay);

vs:

  cmd.Parameters["@BirthdayDay"].Value = NullToZero(dr["obj.BirthdayDay"]);

Some C# guru must know this :-)

Thanks

Charlez
  • 871
  • 3
  • 11
  • 17
  • 1
    Did you try `General.NullToEmpty`? In C# you need to include the class name when calling a static method from outside of the class (if not an extension method). – Oded May 19 '13 at 22:03

3 Answers3

2

Accessing a static method in a class requires you to include the owner class

obj.FooField = General.NullToEmpty(dr["Foo"])

jugg1es
  • 1,560
  • 18
  • 33
1

My experience has been that you have a few options:

1) Embed the utility function in a base class that all of your other classes inherit from. This is not really a practical solution because you will probably have classes that inherit from third party or .Net framework classes, which would be very difficult to modify.

2) Use Extension methods to extend your functionality to existing base classes. I think that this would end up being more work than it's worth.

3) Make a very simple-named global method holder class (i.e. Util) and just prefix your methods with this hold name.

We used option 3 to convert a large VB application to C# and it worked quite well. Although it isn't quite a convenient as the VB syntax, once you get used to it, it becomes very easy to work with.

competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • Option 3 works - but is disappointing :-( Just like it took until C# 4.0 to include optional parameters to functions. Why should we have to prefix all these simple UDF's? or better yet - why doesn't C# have simple null to whatever conversions built in? Just making devs write tons of boilerplate code for idiot error trapping? Sorry, I don't mean to be coarse :-) Thanks for the tip. – Charlez May 19 '13 at 23:20
  • Seems using the Util. prefixing option is the least of the evils in this scenario - Extension methods are typical M$ overcomplication - maybe in the next 10 years some vendor will figure out how to null trap automatically with a few heuristics & basic common sense - it's this same crap coding over and over - in all kinds of languages hmmmmm... maybe that will be my doctoral thesis? – Charlez May 20 '13 at 20:46
1

VB.NET adds methods in a Module to the global (unnamed) namespace. This is mostly a back-compat feature, if the team could have removed module support then they would probably have done so. But they couldn't, it would have made it too difficult to port VB6 code to VB.NET. The practice is iffy and doesn't scale at all, you tend to run into trouble when the project becomes large. A problem know as "global namespace pollution".

Programmers tend to work around it by giving method names a prefix. Which works but is pretty awkward since you have to cough up that prefix every time you want to call the method, there is no analogue of the Imports directive for that. IntelliSense suffers greatly as well.

C# just doesn't permit doing this at all. Closest you could get is with extension methods. But don't, get used to the C# Way.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks for the history lesson :-) - what is the 'C# way' you recommend? The Util method competent_tech recommended does 'do the job' and decreases boilerplate code. The question remains as to how to do this without repetitive boilerplate code or prefixing just to perform basic null trapping. Many thanks, mate :-) – Charlez May 20 '13 at 00:40
  • What you call "ugly", C# programmers call "normal". The C# Way is to not think that's ugly. Takes a while. – Hans Passant May 20 '13 at 00:50
  • Welp, I guess the mystery of why startups don't use C# has been solved. They'd be doomed by having to hire developers who think that sort of thing's a good idea -- I know - let's bloat our CRUD code by 30% - we're being paid by the character right? Do please pardon my wee bit of snarkiness... – Charlez May 20 '13 at 16:16
  • Right, the brain transplant is going to hurt for a while. You'll get over it. Or not, there's little reason to avoid using VB.NET, it is a very capable language. Hard to believe that startups favor VB.NET btw, the language has lost of lot of fans since 2008. Linq and lamdas were pivotal. If you look for bloat then C# is not the right choice, you would favor spelling End If instead of } – Hans Passant May 20 '13 at 16:27
  • Actually we're doing the new .NET MVC4 RESTful Web API - pretty cool - C# twerks aside... Html5 + javascript + sass for the front end + Sencha for mobile :-))) - and maybe a dash or two of Python... - just porting some legacy biz logic & CRUD code to C# - thanks for your kind perspective and sage advice. I'd rather be way cool and do node to Mongo, but we're not that hip... – Charlez May 20 '13 at 20:28
  • Global namespace pollution can be a problem if things are added to the global namespace willy-nilly. On the other hand, I don't know that `Math.Sqrt` is more expressive than `Sqrt`. I would have favored as a compromise allowing a class or namespace to explicitly specify static classes whose members should be directly visible in the current context. – supercat Aug 02 '13 at 22:27
  • It is not willy-nilly. The problem with namespace pollution is that there's always a programmer [named Willy](http://stackoverflow.com/a/184673/17034) to give you a hard time. Nilly is his unlikely girl friend, some odds you've never seen her. – Hans Passant Aug 02 '13 at 22:38