views:

223

answers:

4

Hi,

I'm developing a little C# application for the fun. I love this language but something disturb me ...

Is there any way to do a #define (C mode) or a symbol (ruby mode).

The ruby symbol is quite useful. It's just some name preceded by a ":" (example ":guy") every symbol is unique and can be use any where in the code.

In my case i'd like to send a flag (connect or disconnect) to a function.

What is the most elegant C# way to do that ?

Thanks.

Edit : Some examples on how Ruby symbols are used

Here is what i'd like to do :

BgWorker.RunWorkersAsync(:connect)
//...

private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
{
  if (e.Arguement == :connect)
    //Do the job
}

At this point the my favorite answer is the enum solution ;)

A: 

You could use a string constant:

public const string Guy = "guy";

In fact strings in .NET are special. If you declare two string variable with the same value they actually point to the same object:

string a = "guy";
string b = "guy";
Console.WriteLine(object.ReferenceEquals(a, b)); // prints True
Darin Dimitrov
Printing the hash code doesn't show that they're referencing the same object - use object.ReferenceEquals instead. (They *will*, due to literal interning - but your code doesn't actually prove it.)
Jon Skeet
The hash code will match even if they don't point to the same object. The hash code is calculated from the string's contents, not from its memory location. And I wouldn't rely on strings being interned. This is only for literal strings and I would say it's an implementation detail. If you want to be sure that two equivalent strings are indeed the same object, use `string.Intern()`.
P Daddy
Thanks Jon, I've updated the post to reflect your remark.
Darin Dimitrov
A: 

Similar to @Darin but I often create a Defs class in my project to put all such constants so there is an easy way to access them from anywhere.

class Program
{
    static void Main(string[] args)
    {

        string s = Defs.pi;
    }
}
class Defs
{

    public const int Val = 5;
    public const string pi = "3.1459";
} 
rerun
remember to mark Defs as static!
jmservera
Const are static by default take a look at this http://abdullin.com/how-to-run-free-ncover-on-a-64-bit-machine/
rerun
@rerun: I think jmservera is referring to marking the *class* as static. `static class Defs{}`
P Daddy
A bit off topic, but you should use Math.PI in computations. I know it's just an example but may mislead a new programmer to think they need to define PI in their application.
Maggie
+2  A: 

C# doesn't support C-style macros, although it does still have #define. For their reasoning on this take a look at the csharp FAQ blog on msdn.

If your flag is for conditional compilation purposes, then you can still do this:

#define MY_FLAG

#if MY_FLAG
  //do something
#endif

But if not, then what you're describing is a configuration option and should perhaps be stored in a class variable or config file instead of a macro.

Xiaofu
Yes i know this method, it's all but elegant :p In C the define can be use into condition or as function parameters.
Niklaos
Macros used as method substitutes or as global variables tend to obscure the situation in my opinion, and obscurity is anything but elegant. ;) But of course you may well have other things in mind beyond that.
Xiaofu
Look at what you can do with ruby symbols ;) http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol
Niklaos
+4  A: 

In your case, sending a flag can be done by using an enum...

public enum Message
{
  Connect,
  Disconnect
}

public void Action(Message msg)
{
   switch(msg)
   {
      case Message.Connect: 
         //do connect here
       break;
      case Message.Disconnect: 
          //disconnect
       break;
      default:
          //Fail!
       break;
   }
}
jmservera