CSharp Coding Standards

A

auratius

http://www.auratius.co.za/CSharpCodingStandards.html

Complete CSharp Coding Standards
1. Naming Conventions and Styles
2. Coding Practices
3. Project Settings and Project Structure
4. Framework-Specific Guidelines


Naming Conventions and Styles
Use Pascal casing for type and method names and constants:

public class SomeClass
{
const int DefaultSize = 100;
public SomeMethod( )
{}
}


Use camel casing for local variable names and method arguments:

int number;
void MyMethod(int someNumber)
{}


Prefix interface names with I:

interface IMyInterface
{..}


Prefix private member variables with m_.

Suffix custom attribute classes with Attribute.

Suffix custom exception classes with Exception.

Name methods using verb/object pairs, such as ShowDialog( ).

Methods with return values should have names describing the values
returned, such as GetObjectState( ).

Use descriptive variable names.

Avoid single-character variable names, such as i or t. Use index or
temp instead.

Avoid using Hungarian notation for public or protected members.

Avoid abbreviating words (such as num instead of number).

Always use C# predefined types, rather than the aliases in the System
namespace. For example:

object NOT Object
string NOT String
intNOT Int32


With generics, use capital letters for types. Reserve suffixing Type
for when dealing with the .NET type Type:

//Correct:
public class LinkedList<K,T>
{...}
//Avoid:
public class LinkedList<KeyType,DataType>
{...}


Use meaningful namespace names, such as the product name or the
company name.

Avoid fully qualified type names. Use the using statement instead.

Avoid putting a using statement inside a namespace.

Group all framework namespaces together and put custom or third-party
namespaces underneath:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using MyCompany;
using MyControls;


Use delegate inference instead of explicit delegate instantiation:

delegate void SomeDelegate( );
public void SomeMethod( )
{...}
SomeDelegate someDelegate = SomeMethod;


Maintain strict indentation. Do not use tabs or nonstandard
indentation, such as one space. Recommended values are three or four
spaces.

Indent comments at the same level of indentation as the code that you
are documenting.

All comments should pass spellchecking. Misspelled comments indicate
sloppy development.

All member variables should be declared at the top, with one line
separating them from the properties or methods:

public class MyClass
{
int m_Number; string m_Name;

public void SomeMethod1( )
{}
public void SomeMethod2( )
{}
}


Declare a local variable as close as possible to its first use.

A filename should reflect the class it contains.

When using partial types and allocating a part per file, name each
file after the logical part that part plays. For example:

//In MyClass.cs
public partial class MyClass
{...}
//In MyClass.Designer.cs
public partial class MyClass
{...}


Always place an open curly brace ({) in a new line.

With anonymous methods, mimic the code layout of a regular method,
aligned with the anonymous delegate declaration (this complies with
placing an open curly brace in a new line):

delegate void SomeDelegate(string someString);
//Correct:
public void InvokeMethod( )
{
SomeDelegate someDelegate = delegate(string name)
{
MessageBox.Show(name);
};
someDelegate("Juval");
}
//Avoid
public void InvokeMethod( )
{
SomeDelegate someDelegate = delegate(string name)
{MessageBox.Show(name);};
someDelegate("Juval");
}


Use empty parentheses on parameter-less anonymous methods. Omit the
parentheses only if the anonymous method could have been used on any
delegate:

delegate void SomeDelegate( );
//Correct
SomeDelegate someDelegate1 = delegate( )
{
MessageBox.Show("Hello");
};
//Avoid
SomeDelegate someDelegate1 = delegate
{
MessageBox.Show("Hello");
};



Coding Practices
Avoid putting multiple classes in a single file.

A single file should contribute types to only a single namespace.
Avoid having multiple namespaces in the same file.

Avoid files with more than 500 lines (excluding machine-generated
code).

Avoid methods with more than 25 lines.

Avoid methods with more than five arguments. Use structures for
passing multiple arguments.

Lines should not exceed 80 characters.

Do not manually edit any machine-generated code.

If modifying machine-generated code, modify the format and style to
match this coding standard.

Use partial classes whenever possible to factor out the maintained
portions.

Avoid comments that explain the obvious. Code should be self-
explanatory. Good code with readable variable and method names should
not require comments.

Document only operational assumptions, algorithm insights, and so on.

Avoid method-level documentation.

Use extensive external documentation for API documentation.

Use method-level comments only as tool tips for other developers.

With the exception of zero and one, never hardcode a numeric value;
always declare a constant instead.

Use the const directive only on natural constants, such as the number
of days of the week.

Avoid using const on read-only variables. For that, use the readonly
directive:

public class MyClass
{
public const int DaysInWeek = 7;
public readonlyint Number;
public MyClass(int someValue)
{
Number = someValue;
}
}


Assert every assumption. On average, every fifth line is an assertion:

using System.Diagnostics;

object GetObject( )
{...}

object someObject = GetObject( );
Debug.Assert(someObject != null);


Every line of code should be walked through in a "white box" testing
manner.

Catch only exceptions for which you have explicit handling.

In a catch statement that throws an exception, always throw the
original exception (or another exception constructed from the original
exception) to maintain the stack location of the original error:

catch(Exception exception)
{
MessageBox.Show(exception.Message);
throw; //Same as throw exception;
}


Avoid error code as method return values.

Avoid defining custom exception classes.

When defining custom exceptions:

Derive the custom exception from Exception.

Provide custom serialization.

Avoid multiple Main( ) methods in a single assembly.

Make only the most necessary types public; mark others as internal.

Avoid friend assemblies, as they increase interassembly coupling.

Avoid code that relies on an assembly running from a particular
location.

Minimize code in application assemblies (i.e., EXE client assemblies).
Use class libraries instead to contain business logic.

Avoid providing explicit values for enums:

//Correct
public enum Color
{
Red,Green,Blue
}
//Avoid
public enum Color
{
Red = 1,Green = 2,Blue = 3
}


Avoid specifying a type for an enum:

//Avoid
public enum Color : long
{
Red,Green,Blue
}


Always use a curly brace scope in an if statement, even if it contains
a single statement.

Avoid using the trinary conditional operator.

Avoid function calls in Boolean conditional statements. Assign into
local variables and check on them:

bool IsEverythingOK( )
{...}
//Avoid:
if(IsEverythingOK( ))
{...}
//Correct:
bool ok = IsEverythingOK( );
if(ok)
{...}


Always use zero-based arrays.

Always explicitly initialize an array of reference types:

public class MyClass
{}
const int ArrraySize = 100;
MyClass[] array = new MyClass[ArrraySize];
for(int index = 0; index < array.Length; index++)
{
array[index] = new MyClass( );
}


Do not provide public or protected member variables. Use properties
instead.

Avoid using the new inheritance qualifier. Use override instead.

Always mark public and protected methods as virtual in a non-sealed
class.

Never use unsafe code, except when using interop.

Avoid explicit casting. Use the as operator to defensively cast to a
type:

Dog dog = new GermanShepherd( );
GermanShepherd shepherd = dog asGermanShepherd;
if(shepherd != null)
{...}


Always check a delegate for null before invoking it.

Do not provide public event member variables. Use event accessors
instead.

Avoid defining event-handling delegates. Use GenericEventHandler
instead.

Avoid raising events explicitly. Use EventsHelper to publish events
defensively.

Always use interfaces.

Classes and interfaces should have at least a 2:1 ratio of methods to
properties.

Avoid interfaces with one member.

Strive to have three to five members per interface.

Do not have more than 20 members per interface. The practical limit is
probably 12.

Avoid events as interface members.

When using abstract classes, offer an interface as well.

Expose interfaces on class hierarchies.

Prefer using explicit interface implementation.

Never assume a type supports an interface. Defensively query for that
interface:

SomeType obj1;
IMyInterface obj2;

/* Some code to initialize obj1, then: */
obj2 = obj1 as IMyInterface;
if(obj2 != null)
{
obj2.Method1( );
}
else
{
//Handle error in expected interface
}


Never hardcode strings that will be presented to end users. Use
resources instead.

Never hardcode strings that might change based on deployment, such as
connection strings.

Use String.Empty instead of "":

//Avoid
string name = "";

//Correct
string name = String.Empty;


When building a long string, use StringBuilder, not string.

Avoid providing methods on structures.

Parameterized constructors are encouraged.

You can overload operators.

Always provide a static constructor when providing static member
variables.

Do not use late-binding invocation when early binding is possible.

Use application logging and tracing.

Never use goto, except in a switch statement fall-through.

Always have a default case in a switch statement that asserts:

int number = SomeMethod( );
switch(number)
{
case 1:
Trace.WriteLine("Case 1:");
break;
case 2:
Trace.WriteLine("Case 2:");
break;
default:
Debug.Assert(false);
break;
}


Do not use the this reference unless invoking another constructor from
within a constructor:

//Example of proper use of 'this'
public class MyClass
{
public MyClass(string message)
{}
public MyClass( ) : this("Hello")
{}
}


Do not use the base word to access base class members unless you wish
to resolve a conflict with a subclass member of the same name or when
invoking a base class constructor:

//Example of proper use of 'base'
public class Dog
{
public Dog(string name)
{}
virtual public void Bark(int howLong)
{}
}
public class GermanShepherd : Dog
{
public GermanShepherd(string name) : base(name)
{}
override public void Bark(int howLong)
{
base.Bark(howLong);
}
}


Do not use GC.AddMemoryPressure( ).

Do not rely on HandleCollector.

Implement Dispose( ) and Finalize( ) methods based on the template in
Examples.

Always run code unchecked by default (for the sake of performance),
but explicitly in checked mode for overflow- or underflow-prone
operations:

int CalcPower(int number,int power)
{
int result = 1;
for(int count = 1;count <= power;count++)
{
checked
{
result *= number;
}
}
return result;
}


Avoid explicit code exclusion of method calls (#if...#endif). Use
conditional methods instead:

public class MyClass
{
[Conditional("MySpecialCondition")]
public void MyMethod( )
{}
}


Avoid casting to and from System.Object in code that uses generics.
Use constraints or the as operator instead:

class SomeClass
{}
//Avoid:
class MyClass<T>
{
void SomeMethod(T t)
{
object temp = t;
SomeClass obj = (SomeClass)temp;
}
}
//Correct:
class MyClass<T> where T : SomeClass
{
void SomeMethod(T t)
{
SomeClass obj = t;
}
}


Do not define constraints in generic interfaces. Interface-level
constraints can often be replaced by strong typing:

public class Customer
{...}
//Avoid:
public interface IList<T> where T : Customer
{...}
//Correct:
public interface ICustomerList : IList<Customer>
{...}


Do not define method-specific constraints in interfaces.

If a class or a method offers both generic and non-generic flavors,
always prefer using the generics flavor.

When implementing a generic interface that derived from an equivalent
non-generic interface (such as IEnumerable<T>), use explicit interface
implementation on all methods, and implement the non-generic methods
by delegating to the generic ones:

class MyCollection<T> : IEnumerable<T>
{
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{...}
IEnumerator IEnumerable.GetEnumerator()
{
IEnumerable<T> enumerable = this;
return enumerable.GetEnumerator();
}
}



Project Settings and Project Structure
Always build your projects with Warning Level 4 (see Figure E-1).

Treat warnings as errors in the Release build (note that this is not
the default of Visual Studio). Although it is optional, this standard
recommends treating warnings as errors in Debug builds as well.

Avoid suppressing specific compiler warnings.

Always explicitly state your supported runtime versions in the
application configuration file:

<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.5500.0"/>
<supportedRuntime version="v1.1.5000.0"/>
</startup>
</configuration>



Figure E-1. The project Build pane




Avoid explicit custom version redirection and binding to CLR
assemblies.

Avoid explicit preprocessor definitions (#define). Use the project
settings for defining conditional compilation constants.

Do not put any logic inside AssemblyInfo.cs.

Do not put any assembly attributes in any file other than
AssemblyInfo.cs.

Populate all fields in AssemblyInfo.cs, such as company name,
description, and copyright notice.

All assembly references should use relative paths.

Disallow cyclic references between assemblies.

Avoid multi-module assemblies.

Avoid tampering with exception handling using the Exception window
(Debug -> Exceptions).

Strive to use uniform version numbers on all assemblies and clients in
the same logical application (typically, a solution). Use the
SolutionInfo.cs technique from Examples to automate.

Name your Visual Studio 2005 application configuration file
App.config, and include it in the project.

Modify the Visual Studio 2005 default project structure to your
project's standard layout, and apply a uniform structure for project
folders and files.

A release build should contain debug symbols (see Figure E-2).


Figure E-2. The Advanced Build Settings dialog



Always sign your assemblies, including the client applications.

Use password-protected keys.



Framework-Specific Guidelines
Multithreading
Use synchronization domains. Avoid manual synchronization, because
that often leads to deadlocks and race conditions.

Never call outside your synchronization domain.

Manage asynchronous call completion on a callback method. Do not wait,
poll, or block for completion.

Always name your threads:

Thread currentThread = Thread.CurrentThread;
string threadName = "Main UI Thread";
currentThread.Name = threadName;


The name is traced in the debugger Threads window, making debug
sessions more productive.

Do not call Suspend( ) or Resume( ) on a thread.

Do not call Thread.Sleep( ), except in the following conditions:

Thread.Sleep(0) is an acceptable optimization technique to force a
context switch.

Thread.Sleep( ) is acceptable in testing or simulation code.

Do not call THRead.SpinWait( ).

Do not call Thread.Abort( ) to terminate threads. Use a
synchronization object instead to signal the thread to terminate.

Avoid explicitly setting the thread priority to control execution. You
can set the thread priority based on task semantics (such as
ThreadPriority.BelowNormal for a screensaver).

Do not read the value of the ThreadState property. Use
Thread.IsAlive( ) to determine whether the thread is dead or alive.

Do not rely on setting the thread type to background thread for
application shutdown. Use a watchdog or other monitoring entity to
deterministically kill threads.

Do not use the thread local storage unless thread affinity is
guaranteed.

Do not call Thread.MemoryBarrier( ).

Never call Thread.Join( ) without checking that you are not joining
your own thread:

void WaitForThreadToDie(Thread thread)
{
Debug.Assert(Thread.CurrentThread.ManagedThreadId !=
thread.ManagedThreadId);
thread.Join( );
}


Always use the lock( ) statement rather than explicit Monitor
manipulation.

Always encapsulate the lock( ) statement inside the object it
protects:

public class MyClass
{
public void DoSomething( )
{
lock(this)
{...}
}
}


You can use synchronized methods instead of writing the lock( )
statement yourself.

Avoid fragmented locking.

Avoid using a Monitor to wait or pulse objects. Use manual or auto-
reset events instead.

Do not use volatile variables. Lock your object or fields instead to
guarantee deterministic and thread-safe access. Do not use
THRead.VolatileRead( ), Thread.VolatileWrite( ), or the volatile
modifier.

Avoid increasing the maximum number of threads in the thread pool.

Never stack lock( ) statements, because that does not provide atomic
locking:

MyClass obj1 = new MyClass( );
MyClass obj2 = new MyClass( );
MyClass obj3 = new MyClass( );

//Do not stack lock statements
lock(obj1)
lock(obj2)
lock(obj3)
{
obj1.DoSomething( );
obj2.DoSomething( );
obj3.DoSomething( );
}


Use WaitHandle.WaitAll( ) instead.

Serialization
Prefer the binary formatter.

Mark serialization event-handling methods as private.

Use the generic IGenericFormatter interface.

Always mark non-sealed classes as serializable.

When implementing IDeserializationCallback on a non-sealed class, make
sure to do so in a way that allows subclasses to call the base class
implementation of OnDeserialization( ).

Always mark unserializable member variables as non-serializable.

Always mark delegates on a serialized class as non-serializable
fields:

[Serializable]
public class MyClass
{
[field:NonSerialized]
public event EventHandler MyEvent;
}


Remoting
Prefer administrative configuration to programmatic configuration.

Always implement IDisposable on single-call objects.

Always prefer a TCP channel and a binary format when using remoting,
unless a firewall is present.

Always provide a null lease for a singleton object:

public class MySingleton : MarshalByRefObject
{
public override object InitializeLifetimeService( )
{
return null;
}
}


Always provide a sponsor for a client-activated object. The sponsor
should return the initial lease time.

Always unregister the sponsor on client application shutdown.

Always put remote objects in class libraries.

Avoid using SoapSuds.exe.

Avoid hosting in IIS.

Avoid using uni-directional channels.

Always load a remoting configuration file in Main( ), even if the file
is empty and the application does not use remoting:

static void Main( )
{
RemotingConfigurationEx.Configure( );
/* Rest of Main( ) */
}


Avoid using Activator.GetObject( ) and Activator.CreateInstance( ) for
remote object activation. Use new instead.

Always register port 0 on the client side, to allow callbacks.

Always elevate type filtering to Full on both client and host, to
allow callbacks.

Security
Always demand your own strong name on assemblies and components that
are private to the application, but are public (so that only you can
use them):

public class PublicKeys
{
public const string MyCompany =
"1234567894800000940000000602000000240000"+

"52534131000400000100010007D1FA57C4AED9F0"+

"A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C83"+

"4C99921EB23BE79AD9D5DCC1DD9AD23613210290"+

"0B723CF980957FC4E177108FC607774F29E8320E"+

"92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99"+

"285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF"+

"0FC4963D261C8A12436518206DC093344D5AD293";
}

[StrongNameIdentityPermission(SecurityAction.LinkDemand,
PublicKey = PublicKeys.MyCompany)]
public class MyClass
{...}


Apply encryption and security protection on application configuration
files.

When importing an interop method, assert unmanaged code permission and
demand appropriate permission instead:

[DllImport("user32",EntryPoint="MessageBoxA")]
private static extern int Show(IntPtr handle,string text,string
caption,

int msgType);
[SecurityPermission(SecurityAction.Assert,UnmanagedCode = true)]
[UIPermission(SecurityAction.Demand,
Window =
UIPermissionWindow.SafeTopLevelWindows)]
public static void Show(string text,string caption)
{
Show(IntPtr.Zero,text,caption,0);
}


Do not suppress unmanaged code access via the
SuppressUnmanagedCodeSecurity attribute.

Do not use the /unsafe switch of TlbImp.exe. Wrap the RCW in managed
code so that you can assert and demand permissions declaratively on
the wrapper.

On server machines, deploy a code access security policy that grants
only Microsoft, ECMA, and self (identified by a strong name) full
trust. Code originating from anywhere else is implicitly granted
nothing.

On client machines, deploy a security policy that grants client
application only the permissions to execute, to call back the server,
and to potentially display user interface. When not using ClickOnce,
client application should be identified by a strong name in the code
groups.

To counter a luring attack, always refuse at the assembly level all
permissions not required to perform the task at hand:

[assembly:UIPermission(SecurityAction.RequestRefuse,
Window=UIPermissionWindow.AllWindows)]


Always set the principal policy in every Main( ) method to Windows:

public class MyClass
{
static void Main( )
{
AppDomain currentDomain = AppDomain.CurrentDomain;

currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
}
//other methods
}


Never assert a permission without demanding a different permission in
its place.

For more information goto

http://www.auratius.co.za

Regards

Auratius
 
M

Marc Gravell

And your point? MS have a good set of standards / guidelines that
aren't very different, so I hop this didn't take you too long... I'd
also arge some of these... (not exhaustive...)

i.e. SomeClass<K, T> should probably be SomeClass<TKey, TValue>

declaring members at the top... why? it adds no value in a modern
editor; keep it near (adjacent to) the property that manages it...

m_ : it's a marmite thing

brace layout : don't start that war!

your enum example is counter to the statement

"always mark public and protected methods as virtual"... woah that is
risky. If your class doesn't explicitely anticipate inheritance on a
method, it could be relying on the implementation. I'm not saying
don't use virtuals, but "always" is the road to madness

"do not provide public event member variables" - no such thing exists.
An "event" is explicitely not a field (variable); however "do not
provide public delegate fields that expose events" would be
reasonable.

EventsHelper - is that bespoke? never heard of it; neither has
Reflector

2:1 ratio methods to properties; rubbish; it should have what the
scenario requires

String.Empty vs. ""; no practial benefit given compiler support,
interning etc. I find "" clearer, so I use it

"Do not use the this reference unless" ... a few more usages
present... e.g. as "sender", testing object references, etc

lock(this) - is frowned upon in some circles; you don't know who else
can lock on your reference; lock on a private readonly object instead
(or a private collection if that is what you are synchronising)

Monitor.Pulse - why not? Works very cleanly without requiring an OS
object (AFAIK)

Marc
 
N

Nobody

String.Empty vs. ""; no practial benefit given compiler support, interning
etc. I find "" clearer, so I use it

I didnt read his recommandations but only your comments.

My 2 cents on String.Empty: as it's a static member of String, you probably
already know that each time you use it you point on the same instance of it.
Performance.

I did a quick test and compile a consoleapp where I compare strings with "".
The compiler doesn't substitute "" with String.Empy. So, I suppose, at
runtime, "" is *each time* converted to a new string object. Bad
performance.

Maybe I'm wrong, any CLR specialist could add his comments on this?
 
N

Nobody

Maybe I'm wrong, any CLR specialist could add his comments on this?

Okay, after 5 minutes test and playing with ildasm.exe it can say that "" is
not replaced by String.Empty.

---8<---
IL_0001: ldstr "a"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr ""
IL_000d: call bool [mscorlib]System.String::blush:p_Equality(string,
string)

IL_002a: ldc.i4.0
IL_002b: ceq
IL_002d: stloc.1
IL_002e: ldloc.1
IL_002f: brtrue.s IL_0037
IL_0031: ldstr "d"
IL_0036: stloc.0
IL_0037: ldloc.0
IL_0038: ldsfld string [mscorlib]System.String::Empty
IL_003d: call bool [mscorlib]System.String::blush:p_Equality(string,
string)

---8<---
 
C

Christof Nordiek

I did a quick test and compile a consoleapp where I compare strings with
"". The compiler doesn't substitute "" with String.Empy. So, I suppose, at
runtime, "" is *each time* converted to a new string object. Bad
performance.
<snip>
Surely not, all string literal with the same value only constitute only one
stringinstance.

As long, as string values aren't constructed by operators or similar, there
will never be two equal string instances.

Christof
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Marc Gravell said:
And your point? MS have a good set of standards / guidelines that aren't
very different, so I hop this didn't take you too long... I'd also arge
some of these... (not exhaustive...)

I'm impress that you took the time to read it :)
i.e. SomeClass<K, T> should probably be SomeClass<TKey, TValue>

declaring members at the top... why? it adds no value in a modern editor;
keep it near (adjacent to) the property that manages it...
Agreed

m_ : it's a marmite thing



lock(this) - is frowned upon in some circles; you don't know who else can
lock on your reference; lock on a private readonly object instead (or a
private collection if that is what you are synchronising)

Jon Sket has a VERY GOOD explanation of why you should NEVER use lock(this)
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Nobody said:
I didnt read his recommandations but only your comments.

My 2 cents on String.Empty: as it's a static member of String, you
probably already know that each time you use it you point on the same
instance of it. Performance.

I did a quick test and compile a consoleapp where I compare strings with
"". The compiler doesn't substitute "" with String.Empy. So, I suppose, at
runtime, "" is *each time* converted to a new string object. Bad
performance.

The last statement is incorrect, all string literals used in your code are
stored only once and that same reference is used all over the code.

It's the compiler decision if create a new reference to "" or use
String.Empty instead, in any case I see no difference in performance in
either case.
 
N

Nobody

The last statement is incorrect, all string literals used in your code are
stored only once and that same reference is used all over the code.

It's the compiler decision if create a new reference to "" or use
String.Empty instead, in any case I see no difference in performance in
either case.


OKay, thanks Christof/Ignacio for your comments, i'm glad that i've learned
something today. My test was too simplistic, only 3 lines of code, didn't
tried with multiple "" in code.

Why the hell did they implement String.Empty then?

---8<---
public static readonly string Empty;
static String()
{
Empty = "";
WhitespaceChars = new char[] {
'\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', '\u1680',
'\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006',
'\u2007', '\u2008', '\u2009', '\u200a', '\u200b', '\u2028',
'\u2029', '\u3000', '\ufeff'
};
}

I can understand that Environment.NewLine can be different on different
platform, but an empty string is kinda always the same...
 
P

Paul Werkowitz

Am 29 Mar 2007 03:44:26 -0700 schrieb (e-mail address removed):

Hello,

sorry, but much of this is a matter of taste. Like driving on the left side
or right side of the street. Different countries came to different
solutions.

Unfortunately, you did not give any reasoning for your "standards". For
example, *why* do you discourage the use of single character variable
names? Pls give arguments for your recommendations. Without that, your
"Standards" are no better or worse than any of the many other already
existing recomendations.

In *my* coding standards, the according passage reads: "Variables with
longer lifespan should have longer, more descriptive names. Variables with
short lifespan should have shorter names. Longer names express what the
variable stores ("Person", "UserId"). Shorter names express what a variable
is used for (e.g. i, j as loop counters)".

And: I personally strongly recommend the use of the shortest meaningful
variable names - but no shorter.

OK - see the difference? And btw, "temp" is in no way any better than "t".

Some of your recommendations are really questionable, and are frowned upon
by most professionals.
All member variables should be declared at the top, with one line
separating them from the properties or methods:

public class MyClass
{
int m_Number; string m_Name;

public void SomeMethod1( )
{}
public void SomeMethod2( )
{}
}

First of all, besides of personal preferences there are good reasons *not*
to write it like this. When we open a file to look at a class, we are
mainly interested in the public parts of the class - that is what we can
use. Private parts are implementation business and should not be visible at
all. From that follows that private methods and private variables should be
at the very end.

In *my* coding standards, I recommend to use the partial class feature to
separate public parts from implementation details. And I strongly recommend
to delegate work to the implementation parts. Sourcecode of public
functions should be very short.


About 80% Some of your recommendations are not even questionable, they are
plain dead wrong. I don't want to go into it deeper, but if someone wants I
can give more thorough analysis of many of the points. Simply one example:
Always mark public and protected methods as virtual in a non-sealed
class.

Sorry, but the other way around is correct: "Never make a public function
virtual", or "all virtual functions should be non-public (which leaves
protected, of course.)

Why? Because the publicly exposed interface of a class is defined by its
public members (functions, here.) Whether a class allows to "plug in"
another implementation for a certain service it offers, and how this is
technically done, is an implementation detail. Such a plug-in *can* be
realised by making a function virtual: we "plug-in" another implementation
by deriving from the class and overriduing the function. BUT - and thats
the important part - the *interface to the class* must remain the same. For
example, checking of preconditions should be in the public function. If
this were virtual, one could simpley derive and omit the checks..... no
good idea. (BTW, there are other techniques to plug-in functionality:
delegates are an example).


OK, one more.......
Assert every assumption. On average, every fifth line is an assertion:

object someObject = GetObject( );
Debug.Assert(someObject != null);

Sorry, completely wrong.

- if GetObject's contract says that it must return an object, then we do
not need to test it after the call. (Of cource, GetObject will throw an
exception should it find that it cannot fulfil its contract).

- but if Getobject's contract says that it can return null, then we
eventualy must write

object someObject = GetObject( );
if ( someObject != null )
{
...
}

etc.


My 2 cents....
Paule
 
B

Brian Gideon

[snip]
Always have a default case in a switch statement that asserts:

int number = SomeMethod( );
switch(number)
{
case 1:
Trace.WriteLine("Case 1:");
break;
case 2:
Trace.WriteLine("Case 2:");
break;
default:
Debug.Assert(false);
break;

}

I like this pattern as well.

void Foo()
{
int number = SomeMethod();
switch (number)
{
case 1: /* blaa blaa */ return Something;
case 2: /* blaa blaa */ return SomethingElse;
}
return DefaultValue;
}
Do not use the this reference unless invoking another constructor from
within a constructor:

I care that much as long as the this keyword is used consistently or
not at all. Using it only half the time is pretty annoying.
Never call Thread.Join( ) without checking that you are not joining
your own thread:

That's too restriction. In fact, I can't think of situation where any
of my code could call Join on its own thread.
 
B

Brian Gideon

Nice...I spent a lot of time making comments on the 3/4 of the list
and all I see are my comments on the last 1/4. I'm not about to redo
it though :)
 
J

Jay

Always use C# predefined types, rather than the aliases in the System
namespace. For example:
object NOT Object
string NOT String
int NOT Int32

I've heard this one before. Could someone give me reasons why using String,
Int32, etc is a bad idea?



http://www.auratius.co.za/CSharpCodingStandards.html

Complete CSharp Coding Standards
1. Naming Conventions and Styles
2. Coding Practices
3. Project Settings and Project Structure
4. Framework-Specific Guidelines


Naming Conventions and Styles
Use Pascal casing for type and method names and constants:

public class SomeClass
{
const int DefaultSize = 100;
public SomeMethod( )
{}
}


Use camel casing for local variable names and method arguments:

int number;
void MyMethod(int someNumber)
{}


Prefix interface names with I:

interface IMyInterface
{..}


Prefix private member variables with m_.

Suffix custom attribute classes with Attribute.

Suffix custom exception classes with Exception.

Name methods using verb/object pairs, such as ShowDialog( ).

Methods with return values should have names describing the values
returned, such as GetObjectState( ).

Use descriptive variable names.

Avoid single-character variable names, such as i or t. Use index or
temp instead.

Avoid using Hungarian notation for public or protected members.

Avoid abbreviating words (such as num instead of number).

Always use C# predefined types, rather than the aliases in the System
namespace. For example:

object NOT Object
string NOT String
intNOT Int32


With generics, use capital letters for types. Reserve suffixing Type
for when dealing with the .NET type Type:

//Correct:
public class LinkedList<K,T>
{...}
//Avoid:
public class LinkedList<KeyType,DataType>
{...}


Use meaningful namespace names, such as the product name or the
company name.

Avoid fully qualified type names. Use the using statement instead.

Avoid putting a using statement inside a namespace.

Group all framework namespaces together and put custom or third-party
namespaces underneath:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using MyCompany;
using MyControls;


Use delegate inference instead of explicit delegate instantiation:

delegate void SomeDelegate( );
public void SomeMethod( )
{...}
SomeDelegate someDelegate = SomeMethod;


Maintain strict indentation. Do not use tabs or nonstandard
indentation, such as one space. Recommended values are three or four
spaces.

Indent comments at the same level of indentation as the code that you
are documenting.

All comments should pass spellchecking. Misspelled comments indicate
sloppy development.

All member variables should be declared at the top, with one line
separating them from the properties or methods:

public class MyClass
{
int m_Number; string m_Name;

public void SomeMethod1( )
{}
public void SomeMethod2( )
{}
}


Declare a local variable as close as possible to its first use.

A filename should reflect the class it contains.

When using partial types and allocating a part per file, name each
file after the logical part that part plays. For example:

//In MyClass.cs
public partial class MyClass
{...}
//In MyClass.Designer.cs
public partial class MyClass
{...}


Always place an open curly brace ({) in a new line.

With anonymous methods, mimic the code layout of a regular method,
aligned with the anonymous delegate declaration (this complies with
placing an open curly brace in a new line):

delegate void SomeDelegate(string someString);
//Correct:
public void InvokeMethod( )
{
SomeDelegate someDelegate = delegate(string name)
{
MessageBox.Show(name);
};
someDelegate("Juval");
}
//Avoid
public void InvokeMethod( )
{
SomeDelegate someDelegate = delegate(string name)
{MessageBox.Show(name);};
someDelegate("Juval");
}


Use empty parentheses on parameter-less anonymous methods. Omit the
parentheses only if the anonymous method could have been used on any
delegate:

delegate void SomeDelegate( );
//Correct
SomeDelegate someDelegate1 = delegate( )
{
MessageBox.Show("Hello");
};
//Avoid
SomeDelegate someDelegate1 = delegate
{
MessageBox.Show("Hello");
};



Coding Practices
Avoid putting multiple classes in a single file.

A single file should contribute types to only a single namespace.
Avoid having multiple namespaces in the same file.

Avoid files with more than 500 lines (excluding machine-generated
code).

Avoid methods with more than 25 lines.

Avoid methods with more than five arguments. Use structures for
passing multiple arguments.

Lines should not exceed 80 characters.

Do not manually edit any machine-generated code.

If modifying machine-generated code, modify the format and style to
match this coding standard.

Use partial classes whenever possible to factor out the maintained
portions.

Avoid comments that explain the obvious. Code should be self-
explanatory. Good code with readable variable and method names should
not require comments.

Document only operational assumptions, algorithm insights, and so on.

Avoid method-level documentation.

Use extensive external documentation for API documentation.

Use method-level comments only as tool tips for other developers.

With the exception of zero and one, never hardcode a numeric value;
always declare a constant instead.

Use the const directive only on natural constants, such as the number
of days of the week.

Avoid using const on read-only variables. For that, use the readonly
directive:

public class MyClass
{
public const int DaysInWeek = 7;
public readonlyint Number;
public MyClass(int someValue)
{
Number = someValue;
}
}


Assert every assumption. On average, every fifth line is an assertion:

using System.Diagnostics;

object GetObject( )
{...}

object someObject = GetObject( );
Debug.Assert(someObject != null);


Every line of code should be walked through in a "white box" testing
manner.

Catch only exceptions for which you have explicit handling.

In a catch statement that throws an exception, always throw the
original exception (or another exception constructed from the original
exception) to maintain the stack location of the original error:

catch(Exception exception)
{
MessageBox.Show(exception.Message);
throw; //Same as throw exception;
}


Avoid error code as method return values.

Avoid defining custom exception classes.

When defining custom exceptions:

Derive the custom exception from Exception.

Provide custom serialization.

Avoid multiple Main( ) methods in a single assembly.

Make only the most necessary types public; mark others as internal.

Avoid friend assemblies, as they increase interassembly coupling.

Avoid code that relies on an assembly running from a particular
location.

Minimize code in application assemblies (i.e., EXE client assemblies).
Use class libraries instead to contain business logic.

Avoid providing explicit values for enums:

//Correct
public enum Color
{
Red,Green,Blue
}
//Avoid
public enum Color
{
Red = 1,Green = 2,Blue = 3
}


Avoid specifying a type for an enum:

//Avoid
public enum Color : long
{
Red,Green,Blue
}


Always use a curly brace scope in an if statement, even if it contains
a single statement.

Avoid using the trinary conditional operator.

Avoid function calls in Boolean conditional statements. Assign into
local variables and check on them:

bool IsEverythingOK( )
{...}
//Avoid:
if(IsEverythingOK( ))
{...}
//Correct:
bool ok = IsEverythingOK( );
if(ok)
{...}


Always use zero-based arrays.

Always explicitly initialize an array of reference types:

public class MyClass
{}
const int ArrraySize = 100;
MyClass[] array = new MyClass[ArrraySize];
for(int index = 0; index < array.Length; index++)
{
array[index] = new MyClass( );
}


Do not provide public or protected member variables. Use properties
instead.

Avoid using the new inheritance qualifier. Use override instead.

Always mark public and protected methods as virtual in a non-sealed
class.

Never use unsafe code, except when using interop.

Avoid explicit casting. Use the as operator to defensively cast to a
type:

Dog dog = new GermanShepherd( );
GermanShepherd shepherd = dog asGermanShepherd;
if(shepherd != null)
{...}


Always check a delegate for null before invoking it.

Do not provide public event member variables. Use event accessors
instead.

Avoid defining event-handling delegates. Use GenericEventHandler
instead.

Avoid raising events explicitly. Use EventsHelper to publish events
defensively.

Always use interfaces.

Classes and interfaces should have at least a 2:1 ratio of methods to
properties.

Avoid interfaces with one member.

Strive to have three to five members per interface.

Do not have more than 20 members per interface. The practical limit is
probably 12.

Avoid events as interface members.

When using abstract classes, offer an interface as well.

Expose interfaces on class hierarchies.

Prefer using explicit interface implementation.

Never assume a type supports an interface. Defensively query for that
interface:

SomeType obj1;
IMyInterface obj2;

/* Some code to initialize obj1, then: */
obj2 = obj1 as IMyInterface;
if(obj2 != null)
{
obj2.Method1( );
}
else
{
//Handle error in expected interface
}


Never hardcode strings that will be presented to end users. Use
resources instead.

Never hardcode strings that might change based on deployment, such as
connection strings.

Use String.Empty instead of "":

//Avoid
string name = "";

//Correct
string name = String.Empty;


When building a long string, use StringBuilder, not string.

Avoid providing methods on structures.

Parameterized constructors are encouraged.

You can overload operators.

Always provide a static constructor when providing static member
variables.

Do not use late-binding invocation when early binding is possible.

Use application logging and tracing.

Never use goto, except in a switch statement fall-through.

Always have a default case in a switch statement that asserts:

int number = SomeMethod( );
switch(number)
{
case 1:
Trace.WriteLine("Case 1:");
break;
case 2:
Trace.WriteLine("Case 2:");
break;
default:
Debug.Assert(false);
break;
}


Do not use the this reference unless invoking another constructor from
within a constructor:

//Example of proper use of 'this'
public class MyClass
{
public MyClass(string message)
{}
public MyClass( ) : this("Hello")
{}
}


Do not use the base word to access base class members unless you wish
to resolve a conflict with a subclass member of the same name or when
invoking a base class constructor:

//Example of proper use of 'base'
public class Dog
{
public Dog(string name)
{}
virtual public void Bark(int howLong)
{}
}
public class GermanShepherd : Dog
{
public GermanShepherd(string name) : base(name)
{}
override public void Bark(int howLong)
{
base.Bark(howLong);
}
}


Do not use GC.AddMemoryPressure( ).

Do not rely on HandleCollector.

Implement Dispose( ) and Finalize( ) methods based on the template in
Examples.

Always run code unchecked by default (for the sake of performance),
but explicitly in checked mode for overflow- or underflow-prone
operations:

int CalcPower(int number,int power)
{
int result = 1;
for(int count = 1;count <= power;count++)
{
checked
{
result *= number;
}
}
return result;
}


Avoid explicit code exclusion of method calls (#if...#endif). Use
conditional methods instead:

public class MyClass
{
[Conditional("MySpecialCondition")]
public void MyMethod( )
{}
}


Avoid casting to and from System.Object in code that uses generics.
Use constraints or the as operator instead:

class SomeClass
{}
//Avoid:
class MyClass<T>
{
void SomeMethod(T t)
{
object temp = t;
SomeClass obj = (SomeClass)temp;
}
}
//Correct:
class MyClass<T> where T : SomeClass
{
void SomeMethod(T t)
{
SomeClass obj = t;
}
}


Do not define constraints in generic interfaces. Interface-level
constraints can often be replaced by strong typing:

public class Customer
{...}
//Avoid:
public interface IList<T> where T : Customer
{...}
//Correct:
public interface ICustomerList : IList<Customer>
{...}


Do not define method-specific constraints in interfaces.

If a class or a method offers both generic and non-generic flavors,
always prefer using the generics flavor.

When implementing a generic interface that derived from an equivalent
non-generic interface (such as IEnumerable<T>), use explicit interface
implementation on all methods, and implement the non-generic methods
by delegating to the generic ones:

class MyCollection<T> : IEnumerable<T>
{
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{...}
IEnumerator IEnumerable.GetEnumerator()
{
IEnumerable<T> enumerable = this;
return enumerable.GetEnumerator();
}
}



Project Settings and Project Structure
Always build your projects with Warning Level 4 (see Figure E-1).

Treat warnings as errors in the Release build (note that this is not
the default of Visual Studio). Although it is optional, this standard
recommends treating warnings as errors in Debug builds as well.

Avoid suppressing specific compiler warnings.

Always explicitly state your supported runtime versions in the
application configuration file:

<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.5500.0"/>
<supportedRuntime version="v1.1.5000.0"/>
</startup>
</configuration>



Figure E-1. The project Build pane




Avoid explicit custom version redirection and binding to CLR
assemblies.

Avoid explicit preprocessor definitions (#define). Use the project
settings for defining conditional compilation constants.

Do not put any logic inside AssemblyInfo.cs.

Do not put any assembly attributes in any file other than
AssemblyInfo.cs.

Populate all fields in AssemblyInfo.cs, such as company name,
description, and copyright notice.

All assembly references should use relative paths.

Disallow cyclic references between assemblies.

Avoid multi-module assemblies.

Avoid tampering with exception handling using the Exception window
(Debug -> Exceptions).

Strive to use uniform version numbers on all assemblies and clients in
the same logical application (typically, a solution). Use the
SolutionInfo.cs technique from Examples to automate.

Name your Visual Studio 2005 application configuration file
App.config, and include it in the project.

Modify the Visual Studio 2005 default project structure to your
project's standard layout, and apply a uniform structure for project
folders and files.

A release build should contain debug symbols (see Figure E-2).


Figure E-2. The Advanced Build Settings dialog



Always sign your assemblies, including the client applications.

Use password-protected keys.



Framework-Specific Guidelines
Multithreading
Use synchronization domains. Avoid manual synchronization, because
that often leads to deadlocks and race conditions.

Never call outside your synchronization domain.

Manage asynchronous call completion on a callback method. Do not wait,
poll, or block for completion.

Always name your threads:

Thread currentThread = Thread.CurrentThread;
string threadName = "Main UI Thread";
currentThread.Name = threadName;


The name is traced in the debugger Threads window, making debug
sessions more productive.

Do not call Suspend( ) or Resume( ) on a thread.

Do not call Thread.Sleep( ), except in the following conditions:

Thread.Sleep(0) is an acceptable optimization technique to force a
context switch.

Thread.Sleep( ) is acceptable in testing or simulation code.

Do not call THRead.SpinWait( ).

Do not call Thread.Abort( ) to terminate threads. Use a
synchronization object instead to signal the thread to terminate.

Avoid explicitly setting the thread priority to control execution. You
can set the thread priority based on task semantics (such as
ThreadPriority.BelowNormal for a screensaver).

Do not read the value of the ThreadState property. Use
Thread.IsAlive( ) to determine whether the thread is dead or alive.

Do not rely on setting the thread type to background thread for
application shutdown. Use a watchdog or other monitoring entity to
deterministically kill threads.

Do not use the thread local storage unless thread affinity is
guaranteed.

Do not call Thread.MemoryBarrier( ).

Never call Thread.Join( ) without checking that you are not joining
your own thread:

void WaitForThreadToDie(Thread thread)
{
Debug.Assert(Thread.CurrentThread.ManagedThreadId !=
thread.ManagedThreadId);
thread.Join( );
}


Always use the lock( ) statement rather than explicit Monitor
manipulation.

Always encapsulate the lock( ) statement inside the object it
protects:

public class MyClass
{
public void DoSomething( )
{
lock(this)
{...}
}
}


You can use synchronized methods instead of writing the lock( )
statement yourself.

Avoid fragmented locking.

Avoid using a Monitor to wait or pulse objects. Use manual or auto-
reset events instead.

Do not use volatile variables. Lock your object or fields instead to
guarantee deterministic and thread-safe access. Do not use
THRead.VolatileRead( ), Thread.VolatileWrite( ), or the volatile
modifier.

Avoid increasing the maximum number of threads in the thread pool.

Never stack lock( ) statements, because that does not provide atomic
locking:

MyClass obj1 = new MyClass( );
MyClass obj2 = new MyClass( );
MyClass obj3 = new MyClass( );

//Do not stack lock statements
lock(obj1)
lock(obj2)
lock(obj3)
{
obj1.DoSomething( );
obj2.DoSomething( );
obj3.DoSomething( );
}


Use WaitHandle.WaitAll( ) instead.

Serialization
Prefer the binary formatter.

Mark serialization event-handling methods as private.

Use the generic IGenericFormatter interface.

Always mark non-sealed classes as serializable.

When implementing IDeserializationCallback on a non-sealed class, make
sure to do so in a way that allows subclasses to call the base class
implementation of OnDeserialization( ).

Always mark unserializable member variables as non-serializable.

Always mark delegates on a serialized class as non-serializable
fields:

[Serializable]
public class MyClass
{
[field:NonSerialized]
public event EventHandler MyEvent;
}


Remoting
Prefer administrative configuration to programmatic configuration.

Always implement IDisposable on single-call objects.

Always prefer a TCP channel and a binary format when using remoting,
unless a firewall is present.

Always provide a null lease for a singleton object:

public class MySingleton : MarshalByRefObject
{
public override object InitializeLifetimeService( )
{
return null;
}
}


Always provide a sponsor for a client-activated object. The sponsor
should return the initial lease time.

Always unregister the sponsor on client application shutdown.

Always put remote objects in class libraries.

Avoid using SoapSuds.exe.

Avoid hosting in IIS.

Avoid using uni-directional channels.

Always load a remoting configuration file in Main( ), even if the file
is empty and the application does not use remoting:

static void Main( )
{
RemotingConfigurationEx.Configure( );
/* Rest of Main( ) */
}


Avoid using Activator.GetObject( ) and Activator.CreateInstance( ) for
remote object activation. Use new instead.

Always register port 0 on the client side, to allow callbacks.

Always elevate type filtering to Full on both client and host, to
allow callbacks.

Security
Always demand your own strong name on assemblies and components that
are private to the application, but are public (so that only you can
use them):

public class PublicKeys
{
public const string MyCompany =
"1234567894800000940000000602000000240000"+

"52534131000400000100010007D1FA57C4AED9F0"+

"A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C83"+

"4C99921EB23BE79AD9D5DCC1DD9AD23613210290"+

"0B723CF980957FC4E177108FC607774F29E8320E"+

"92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99"+

"285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF"+

"0FC4963D261C8A12436518206DC093344D5AD293";
}

[StrongNameIdentityPermission(SecurityAction.LinkDemand,
PublicKey = PublicKeys.MyCompany)]
public class MyClass
{...}


Apply encryption and security protection on application configuration
files.

When importing an interop method, assert unmanaged code permission and
demand appropriate permission instead:

[DllImport("user32",EntryPoint="MessageBoxA")]
private static extern int Show(IntPtr handle,string text,string
caption,

int msgType);
[SecurityPermission(SecurityAction.Assert,UnmanagedCode = true)]
[UIPermission(SecurityAction.Demand,
Window =
UIPermissionWindow.SafeTopLevelWindows)]
public static void Show(string text,string caption)
{
Show(IntPtr.Zero,text,caption,0);
}


Do not suppress unmanaged code access via the
SuppressUnmanagedCodeSecurity attribute.

Do not use the /unsafe switch of TlbImp.exe. Wrap the RCW in managed
code so that you can assert and demand permissions declaratively on
the wrapper.

On server machines, deploy a code access security policy that grants
only Microsoft, ECMA, and self (identified by a strong name) full
trust. Code originating from anywhere else is implicitly granted
nothing.

On client machines, deploy a security policy that grants client
application only the permissions to execute, to call back the server,
and to potentially display user interface. When not using ClickOnce,
client application should be identified by a strong name in the code
groups.

To counter a luring attack, always refuse at the assembly level all
permissions not required to perform the task at hand:

[assembly:UIPermission(SecurityAction.RequestRefuse,
Window=UIPermissionWindow.AllWindows)]


Always set the principal policy in every Main( ) method to Windows:

public class MyClass
{
static void Main( )
{
AppDomain currentDomain = AppDomain.CurrentDomain;

currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
}
//other methods
}


Never assert a permission without demanding a different permission in
its place.

For more information goto

http://www.auratius.co.za

Regards

Auratius
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Nobody said:
OKay, thanks Christof/Ignacio for your comments, i'm glad that i've
learned something today. My test was too simplistic, only 3 lines of code,
didn't tried with multiple "" in code.

Why the hell did they implement String.Empty then?

Maybe for the same reason that int is just a translation for Int32.

or string is equivalent to the framework's String
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


Jay said:
Always use C# predefined types, rather than the aliases in the System
namespace. For example:
object NOT Object
string NOT String
int NOT Int32

I've heard this one before. Could someone give me reasons why using
String,
Int32, etc is a bad idea?

There is no different at all. I bet that if you look at the code generated
by the compiler you will get the same code no matter what option you use.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Ignacio said:
Hi,




There is no different at all. I bet that if you look at the code generated
by the compiler you will get the same code no matter what option you use.

You won't get any takers on that bet. :) The generated code is most
definitely identical.

The only difference between int and Int32 is that the latter one
requires "using System", but why would you not include that in the file?
 
J

Jay

Thanks for your replies. I thought maybe it was considered to be bad style
(not in keeping with C#) but it sounds like it isn't.

Why did C# have its own set of types? Why didn't it just use those of .NET
(String, Int32, etc). Was it to make it look not too dissimilar to C++?

I actually prefer Int32, etc, since I then know how big the integer is.


Ignacio said:
Hi,




There is no different at all. I bet that if you look at the code
generated
by the compiler you will get the same code no matter what option you use.

You won't get any takers on that bet. :) The generated code is most
definitely identical.

The only difference between int and Int32 is that the latter one
requires "using System", but why would you not include that in the file?
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

There is actually one case when you have to use the intrinsic types
instead of the framework types, that I forgot to mention. You can
specify that an enum uses int as internal storage, but you can't specify
that it should use Int32. There might be some more special cases like
this, but other than that, they work the same.

It's commonly suggested that you stick to the intrinsic types, and that
is not bad advice. "int" is easier to read than "Int32".

If you want to emphasise the choise of a 32-bit integer in the code, you
can use Int32 instead of int for that specific declaration.

Another aspect is the similarities with and differences from Java. In
Java the double type is a primitive type, but Double is a class. For a
programmer that is used to Java, there is an element of confusion if you
mix them without reason.
 
R

Ravichandran J.V.

Very surprising post and compilation! Because I am currently working on
just these standards and here is a post on just these topics. So, who
are you, my friend?

Incidentally, the below code from your post makes no sense and cannot be
any part of any standards because it is syntactically incorrect.

Use delegate inference instead of explicit delegate instantiation:

delegate void SomeDelegate( );
public void SomeMethod( )
{...}
SomeDelegate someDelegate = SomeMethod;

The correct way of *inferencing* is as below:

SomeDelegate someDelegate = new SomeDelegate(o.meth);

Or, did you mean some other standard?:)

with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
J

Jon Skeet [C# MVP]

Very surprising post and compilation! Because I am currently working on
just these standards and here is a post on just these topics. So, who
are you, my friend?

Incidentally, the below code from your post makes no sense and cannot be
any part of any standards because it is syntactically incorrect.

Use delegate inference instead of explicit delegate instantiation:

delegate void SomeDelegate( );
public void SomeMethod( )
{...}
SomeDelegate someDelegate = SomeMethod;

That works absolutely fine in C# 2. Here's a short but complete
program demonstrating it:

using System;

delegate void SomeDelegate( );
class Test
{
public static void SomeMethod()
{
}

static void Main()
{
SomeDelegate d = SomeMethod;
}
}

(It's only a static method to make things simpler - from an instance
context it would be fine as an instance method.)

See http://pobox.com/~skeet/csharp/csharp2/delegates.html for more on
this.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top