16

In the "C# Coding Standard" by Juval Lowy available from www.idesign.net, the recomendation is made to use the C# predefined types instead of the aliases in the System namespace, e.g.:

  • object NOT Object
  • string NOT String
  • int NOT Int32

What is the benefit of this? How do they differ? I have followed this advise in my own coding but never knew how they differed.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
DaveB
  • 9,470
  • 4
  • 39
  • 66
  • Whatever you do... Things like `s̶t̶r̶i̶n̶g̶.̶E̶m̶p̶t̶y̶` or `u̶i̶n̶t̶.̶P̶a̶r̶s̶e̶(̶)̶` give me the creeps! A static member access on something that does not look like a class? Brrrr. At first glance it appears like a member access on a local variable. (And don't even get me _started_ on the aesthetics...) – Timo Sep 18 '18 at 14:45

8 Answers8

19

The main time they are unexpectedly different is when someone is stupid enough to call a type (or property /field/etc) String (for example), since string always refers to global::System.String, where-as String could be YourNamespace.String.

The closest you can get to the C# alias is @string, which tends to stick out like a sore thumb.

I prefer the C# aliases.

btw, here's a fun way to mess with anyone using dynamic too much:

using dynamic = System.Object;
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
13

They don't really differ. Personally I use the aliases too, but Jeff Richter advocates the exact opposite. The generated code will be exactly the same. Use whichever you find most readable (and try to be consistent).

One thing most people agree on: when writing an API, use the type name rather than the alias, so:

int ReadInt32()

rather than

int ReadInt()

the int part doesn't matter here - it's not part of the name, and can be displayed appropriately to any consumer using any language... but the method name should be language-neutral, which means using the type name.

One place where you have to use the alias is when specifying the underlying type for an enum:

enum Foo : byte // Valid

enum Foo : System.Byte // Invalid
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • What reasoning does Jeff Richter give for not using the aliases? Any idea why a author like Juval Lowy would recomend using the predefined types? I don't mind programmers recomending one or the other but if you choose to follow their recomendations, you should at least know why. If it just comes down to readability, thats fine, at least you know why you are choosing one way over another. – DaveB Sep 17 '10 at 15:25
  • @DaveB: I can't remember Jeff's reasoning, although I suspect it may be consistency (which I can certainly appreciate). I like the aliases because a) they're shorter (not a huge difference, admittedly); b) they're more familiar from other languages; c) they highlight the fact that they're "built-in" types... although that's somewhat specious when it comes to `decimal`, which doesn't really have built-in CLR support. – Jon Skeet Sep 17 '10 at 16:02
  • To me (admittedly not earth-shattering), the aliases just "feel" more like the abstractions we use for "insulation" in other cases - say, if they ever change the .Net type name, u wouldn't have to change the language built-in alias. – galaxis Jan 23 '19 at 18:40
  • @user1172173: I don't think that's a realistic concern; the equivalent type names are baked into the C# specification, and are really never, ever going to change. – Jon Skeet Jan 23 '19 at 22:17
8

In addition to what Jon said here is another difference.

var x = (Int32)-y;    // Does not compile.

var x = (int)-y;      // Negates the value of y and casts as an int.

This is because of a grammar disambiguation rule defined in §7.6.6 of the C# Programming Language specification.

Jeffrey L Whitledge
  • 58,241
  • 9
  • 71
  • 99
  • 1
    It fails as promised. "To cast a negative value, you must enclose the value in parentheses." Yet it works fine with `(int)`. – Steven Sudit Sep 16 '10 at 21:18
7

I think using the 'blue' int, string, etc.. might be a little more intuitive to read. Otherwise, I use the class when calling a static method on it i.e. Int32.TryParse()

Alex
  • 3,644
  • 2
  • 19
  • 27
  • I've seen this practice before, and for the life of me I can't understand what the reason is behind it. To me it looks like a potential error to say (for example): "string foo = String.Empty;" instead of "string foo = string.Empty;". Is there are particular reason you use the proper class name for statics? – JaredReisinger Sep 16 '10 at 21:06
  • @Jared: This is a pretty standard .NET convention. For example, it's in the Lance Hunt doc. – Steven Sudit Sep 16 '10 at 21:19
  • @Jared: We're discussing something that is strictly stylistic. Just giving my 2c.. – Alex Sep 16 '10 at 21:20
  • My comment was less about using either one form or the other... it was about using *both* at the same time (because I think I totally misread your comment). Looking at it now, it's not clear whether you were advocating "alias for declaration but proper class name for statics", and *that's* what I was trying to understand. – JaredReisinger Oct 01 '10 at 07:43
3

I always use the aliases when specifying the type in a parameter, property or method signature or field (so: almost everywhere) except when calling a static member on such a type.

String.Format("{0}", 1);
Int32.Parse("123");
String.IsNullOrEmpty(value);
Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
  • Any reason, just out of curiosity? – Marc Gravell Sep 17 '10 at 05:38
  • It a matter of style, of course: but since the members are defined on the actual type, I use the actual type name. It is consistent with all other code which calls static members, and while I don't have a real Java background, this practice is required in Java. So people with a Java background will automatically do this. – Daniel A.A. Pelsmaeker Sep 17 '10 at 09:20
1

Here's another compiler-based difference:

public enum MyEnum : Byte {Value1, Value2} //does not compile

public enum MyEnum : byte {Value1, Value2} //ok
KeithS
  • 70,210
  • 21
  • 112
  • 164
0

The only difference is that they're nicer to read (this of course is a matter of opinion). The compiled result is exactly the same bytecode.

Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
0

The Entity Framework code generator uses predefined types, so if you want to be able to implement the Visual Studio 2017 coding style rules fully you will need to choose predefined types (int instead of Int32, etc). Otherwise your generated code will not be in compliance.

(Options->Text Editor->C#->Code Style->General->predefined type preference)

Carter Medlin
  • 11,857
  • 5
  • 62
  • 68