简体   繁体   中英

#define - Migrating C++ to C# or VB.Net

I need some advice on how to do the following in either C# and VB.net.

In C++, in my header file I do the following:

#define  StartButtonPressed  Input[0]==1 // Input is an array declared in .cpp file

In my .cpp file, i have a code something like this:

if(StartButtonPressed)
    // do something

The reason of me doing so is so that my code is easier to read. I tried the same thing in C# but it got error. How could I do the same thing in C# and VB.Net? Please advice. Thanks.

There is no good reason to use a macro for this in C++; you could just as easily make it a function and the code would be far cleaner:

bool IsStartButtonPressed()
{
    return Input[0] == 1;
}

Input should also probably be passed as an argument to the function, but it's hard to tell exactly where that is coming from.

You're best off creating a property in your class

protected bool StartButtonPressed {
   get { return Input[0] == 1; }
}

then your code can be as before

.
.
.
if(StartButtonPressed) {

.
.
.
}

However for consistency with the .net framework I'd suggest calling the property IsStartButtonPressed

If you need to to be evaluated at the point of the if statement then you really need a function or a property. However is this is one time evaluation you can use a field

bool isStartButtonPressed = Input[0] ==1;

If you want may classes to have this functionality then I'd recommend a static function from another class, something like

public static class ButtonChecker {
        public static bool IsPressed(int[] input) {
            return input[0] == 1;
        }
    }

Then you call it anywhere with

if(ButtonChecker.IsPressed(Input)) {
  .
  .
}

But ultimately you cannot use macro's like you're used in C/C++. You shouldn't be worried about performance of properties and functions like this as the CLR jit compiler implementation is very very good for them

Here is an example program:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace ConsoleApplication1 {

    public static class ButtonChecker {
        public static bool IsPressed(int[] input) {
            return input[0] == 1;
        }
    }

    static class Program {

        public static void Main(){
            int[] Input = new int[6] { 1, 0, 2, 3,4 , 1 };

            for(int i = 0; i < Input.Length; ++i){
                Console.WriteLine("{0} Is Pressed = {1}", i, ButtonChecker.IsPressed(Input));
            }
            Console.ReadKey();
        }
    }
}

You could use an enum

public enum buttonCode
{
   startButton = 0,
   stopButton = 1
   // more button definitions
}  

Then maybe one function

public bool IsButtonPressed(b as buttoncode)
{
return Input[b] == 1;
}

Then your calls look like:

if IsButtonPressed(buttonCode.StartButton) {   }

The only changes needed to switch button codes are then in the enum, not spread across multiple functions.

Edited to Add:

If you want individually named functions, you could do this:

public bool IsStartButtonPressed()
{
return Input[buttonCode.StartButton] == 1;
}

Still, all of the edits would be in the enum, not the functions.

Bjarne Stroustrup wrote:

The first rule about macros is: Do not use them if you do not have to. Almost every macro demonstrates a flaw in the programming language, in the program, or in the programmer.

It's worth noting two things here before saying anything else. The first is that "macro" can mean a very different thing in some other languages; one would not make the same statement about Lisp. the second is that Stroustrup is willing to take his share of the blame in saying that one reason for using macros is "a flaw in the programming language", so it's not like he's just being superior in condemning their use.

This case though isn't a flaw in the programming language, except that the language lets you do it in the first place (but has to, to allow other macros). The only purpose of this macro is to make the code harder to read. Just get rid of it. Replace it with some actual C# code like:

private bool StartButtonPressed
{
  get
  {
    return Input[0]==1
  }
}

Edit:

Seeing the comment above about wanting to be faster to code, I would do something like:

private enum Buttons
{
  Start = 0,
  Stop = 1,
  Pause = 2,
  /* ... */
}

private bool IsPressed(Buttons button)
{
  return Input[(int)button] == 1;
}

And then call eg IsPressed(Buttons.Start) . Then I'd fix the C++ to use the same approach too (in C++ I would even be able to leave out the Buttons. where I wanting particularly great concision).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM