C# vs. Java: An Instance of a Class with Static Members

I was working on a project where the goal was to translate/port some Java code to C# code. If the Java code doesn’t use exotic features, porting the Java code to C# code is usually pretty easy. But I’ve run into many interesting scenarios where translating Java to C# is surprisingly tricky.

Consider this Java class:

public class Params {

  public static double foo = 2.0;  // some arbitrary value
  public static double bar = foo * 3.0;  // depends on foo
  
  public static void SetFoo(double f)
  {
    foo = f;
    bar = foo * 3.0;  // must update
  }
  
  // the intent is to create a Params object that has all
  // the values so it can be passed to a method
  public final static Params inst = new Params();
}

The Params class holds values for some software system. The data members are static so you’d access them like

double f = Params.foo;

The tricky part is the “inst” (instance) member. The intent is to export a reference to the entire class so that it can be passed to a function, like:

int x = SomeMethod(Params.inst);

Notice that the inst member is created by calling the default (not explictly defined) Params constructor. Anyway, this technique works in Java. If you try the idea in C#, the code will compile but the inst object cannot access the data members.

I tried many different approaches for porting this idea to Java. I finally came up with a solution which isn’t very elegant, but it works.

So, in C#, class Params would be:

public class Params
{
  public static double foo = 2.0;
  public static double bar = foo * 3;

  public static void SetFoo(double f)
  {
    foo = f;
    bar = foo * 3;  
  }

} 

The C# class is the same as the Java class except I don’t have the “inst” member. Now I add a companion class named ParamsInfo:

public class ParamsInfo
{
  public double foo;
  public double bar;

  public ParamsInfo()
  {
    foo = Params.foo;
    bar = Params.bar;
  }
}

The constructor of the companion class grabs the values from the Params class. The idea is that now you can pass the essential content of the Params class by creating an instance of the ParamsInfo class. For example:

int x = DoSomething(new ParamsInfo());

This problem was surprisingly challenging. It looks very simple, especially after you see the solution, but I spent several hours trying approaches that didn’t quite work.

CSharpVsJava-InstanceOfClassWithStaticMembers

This entry was posted in Miscellaneous. Bookmark the permalink.