aliasing basic types and constants in C#

Asked by At

We have a C++ code that defines a unified naming convention (majorly for multiplatform reasons).
For example:

#define FOO_UINT32 unsigned long
and #define FOO_TRUE true

now, we want to port some of this code to C#.
For the first define in the example I figured out that I need:

using FOO_UINT32 = System.UInt32;

The question is? How do I do the second one?

7 Answers

4
dlev On Best Solutions

Since true is not a type, you can't utilize a using directive to alias it. You can create a static class with a const member to get a similar result:

public static class PortConstants
{
    public const bool FOO_TRUE = true;
}

Then you can say bool x = PortConstants.FOO_TRUE;. I'd recommend just using true, though.

You may also want to drop the using alias for UInt32 as well, since the CLR type won't be changing, and is consistent across platforms for which a CLR implementation is available.

1
Adam Houldsworth On

Well, I advise not doing this at all... you will be safe using System.UInt32 in the C# code in place of FOO_INT32.

With the true option, it is a value so cannot be aliased. You'd need to make a constant, but again, don't unless it's a good constant in the sense of:

public class Constants
{
    public const double PI = 3.14; // good use of constants, accuracy of PI could improve in future.
    public const bool FOO_TRUE = true; // bad use of constants, or at the very least, bad naming
}
0
Jamiec On

Static class with consts maybe

public static class Constants
{
   public const bool FOO_TRUE = true;
}
0
mdm On

C# does provide a #define directive, however

The #define directive cannot be used to declare constant values as is typically done in C and C++. Constants in C# are best defined as static members of a class or struct. If you have several such constants, consider creating a separate "Constants" class to hold them.

You are better off creating a static class and defining them like so:

public const bool FOO_TRUE = true;

I would ask though, why do you want to do this?

2
Lasse Vågsæther Karlsen On

You would need to define a constant, that is the closest you get.

public const bool FOO_TRUE = true;

Also note that the using "trick" to handle the type alias will be for the file it is defined in only.

Now, the bigger question is, are you porting or converting? By porting I mean that you want to keep the ability to try to merge in updates to the original sourcebase into the port.

With a conversion you're basically reimplementing functionality.

If you're doing the latter, you should dispense with these "tricks" altogether and pick a C#/.NET way of doing it instead.

Note that if you use UInt32 in your code, this type will never change to be 16-bit or 64-bit depending on platform, it will always be 32-bit and unsigned. As such, the need for such alias types to handle platform inconsistencies is greatly reduced in .NET and C# so my advice would be to just dispense with that type alias altogether and use UInt32 instead.

The same goes for FOO_TRUE, true will always be a bool type, regardless of platform.

The best thing for forward-going code is to use the idioms of the platform you're programming on.

0
Nicola Musatti On

It's a bad idea in C++, where at the very least you should use typedef. In C# it doesn't make sense as portability is guaranteed by the underlying platform. Just don't do it.

0
Salvatore Previti On

You can also use enums if you need, i usually prefer them than constants.

[Flags]
enum FOO_UINT32 : uint
{
    MyFlag1 = 0x00000002u,
    MyFlag2 = 0x80000000u,
    FOO_TRUE = 1,
}

public static class MyFunctions
{
    public static function MyFunction(FOO_UINT32 value);
}


// In your code

MyFunctions.MyFunction(FOO_UINT32.MyFlag1 | FOO_UINT32.MyFlag2);
MyFunctions.MyFunction(0);
MyFunctions.MyFunction(FOO_UINT32.FOO_TRUE);
MyFunctions.MyFunction((FOO_UINT32)0x123456);

Plus, it don't allows you to pass integer values without a casting, increasing overall readability and reducing risk of errors.

0 is a special case for enums, so it works.