13

In C++, it's easy to write something along the lines of:

#ifdef FAST
typedef Real float;
#endif

#ifdef SLOW
typedef Real double;
#endif

#ifdef SLOWER
typedef Real quad;
#endif

In some common header file so I could simply write one version of code and #define the appropriate version to get different binaries.

I know in C# you can do something similar along the lines of:

using Real = double;

So that you can get the similar semantics to typedefs. But is it possible to do something similar to the C++ code above that I wouldn't have to write in every single file?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Mike Bailey
  • 12,479
  • 14
  • 66
  • 123

3 Answers3

5

Not if you want it to use the inbuilt IL operators - you would have to do it per-file. However, if you don't need that (I suspect you do) you could encapsulate it in a struct:

public struct Real {
     private readonly REAL_TYPE value;
     public(REAL_TYPE value) { this.value = value; }
     // TODO add lots of operators (add, multiply. etc) here...
}

(where REAL_TYPE is a using alias in the single file that declares Real)

For my money, not worth it. And the use if the static operators will be relatively slower that direct IL operations that you would get if it was in-situ.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    So I guess my only real option is a giant block of #if #elses at the top of all of my files. – Mike Bailey Jan 22 '11 at 01:27
  • @Sagekilla or avoid the scenario completely :). – Marc Gravell Jan 22 '11 at 07:43
  • Well, one of my requirements is to be able to specify varying levels of precision used in calculations. There's a speed vs precision trade off, in some instances there's no point in using doubles and in others it's an absolute minimum. – Mike Bailey Jan 22 '11 at 19:12
  • 1
    I'm not sure why did this answer get accepted. This is not helpful at all because `struct Real` will be completely unrelated to the `REAL_TYPE`. Adding all the operations and using it instead of `REAL_TYPE` will be frustrating, even accessing field with original type directly would be rather frustrating as well. Not to mention that chains of aliases created with such an approach would quickly get to an incomprehensible state. – user7860670 May 13 '20 at 12:27
  • @user7860670 it seems to me this answer is just missing one essential point; the `Real` should [define an implicit conversion](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/user-defined-conversion-operators) to REAL_TYPE (and vice-versa), so that you can use it as if it really was the underlying type. – TamaMcGlinn Jun 25 '20 at 08:37
0

Since the release of C#10 this is actually possible with global modifiers for using directives.

#if FAST
global using Real = System.Single;
#else
global using Real = System.Double;
#endif   

Definitely a useful feature in mathy projects in which you sometimes care more about precision then other times.

-3

closest thing would be partial classes. partial classes let you define one class across multiple files.

CodeMonkey1313
  • 15,717
  • 17
  • 76
  • 109