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 e.g. 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).
Related
I'm trying to serialize/deserialize an IEnumerator generated from a function using yield.
I would like to serialize the IEnumerator at any iteration, I don't want to force it to generate all of it values.
I know that the yield keyword generate a class behind the scene, and that why I'm using it, to avoid manually writing iterator, and also to make the code cleaner.
My goal is to make a small game engine similar to Nick Gravelyn - The magic of yield, where each GameElement generate an iterator about his behavior, allowing the programmer to easily control timings (because the iterator allow to interrupt and continue a script). I want to try to add a multiplayer layer on top of that, that why I need to serialize/deserialize an IEnumerator.
Forcing the IEnumerator to generate all of his values also force the game to update, this should be avoided.
My first tentative was somethings like :
using System;
using System.Collections.Generic;
using System.Text.Json;
namespace SerializeTest
{
class Program
{
public static IEnumerator<int> CountTo(int end)
{
for(int i = 1; i <= end; i++)
{
Console.WriteLine("i = " + i);
yield return i;
}
}
static void Main(string[] args)
{
IEnumerator<int> e = CountTo(5);
string json = JsonSerializer.Serialize(e);
Console.WriteLine(json);
var f = JsonSerializer.Deserialize<IEnumerator<int>> (json); // crash because interface
while (f.MoveNext());
}
}
}
But deserializing an interface (IEnumerator<int>) is illegal, we need to know the Type of the object behind IEnumerator<int>.
Since the type is generated by the compiler, I try to use reflection over the Deserialize method in order to call it with the correct type generated by the function CountTo() (SerializeTest.Program+<CountTo>d__0 if you are curious)
So my second tentative was somethings like :
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.Json;
namespace SerializeTest
{
class Program
{
public static IEnumerator<int> CountTo(int end)
{
for(int i = 1; i <= end; i++)
{
Console.WriteLine("i = " + i);
yield return i;
}
}
public static T Deserialize<T>(string json) => JsonSerializer.Deserialize<T>(json); // still crash
static void Main(string[] args)
{
IEnumerator<int> e = CountTo(5);
string json = JsonSerializer.Serialize(e);
Console.WriteLine(json);
Type eType = e.GetType();
MethodInfo method = typeof(Program).GetMethod("Deserialize");
MethodInfo genericMethod = method.MakeGenericMethod(eType);
object fObj = genericMethod.Invoke(null, new object[] { json });
var f = (IEnumerator<int>)fObj;
while (f.MoveNext()) ;
}
}
}
but it still crash when calling JsonSerializer.Deserialize() even if the type is now correct and not an interface.
(System.InvalidOperationException : 'Each parameter in constructor 'Void .ctor(Int32)' on type 'SerializeTest.Program+<CountTo>d__0' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. The match can be case-insensitive.'
)
The format don't have any importance (json, xml...) as long as it is possible to send it to another computer and deserialize it back.
I naively hope that there is a way to Serialize/Deserialize an IEnumerator because a lot of cool stuff can be done with it, although I have some serious doubts about such a things to be possible.
Thank for reading so far.
I naively hope that there is a way to Serialize/Deserialize an IEnumerator because a lot of cool stuff can be done with it, although I have some serious doubts about such a things to be possible.
Sending code (and enumerator state machine generated by the compiler which you are trying to send is basically a code) is far more complex then just serializing it to json/xml/etc. For example Apache Ignite supports sending code to another nodes including assembly peer loading. One of the starting points for investigation can be here.
As for your attempt, as you should have already seen that serialized version of the state machine contains only one one property - Current: {"Current":0} while the generated class contains some other state data looking something like this:
private sealed class <<<Main>$>g__CountTo|0_0>d : IEnumerator<int>, IEnumerator, IDisposable
{
private int <>1__state;
private int <>2__current;
public int end;
private int <i>5__1;
int IEnumerator<int>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
// ... rest of the generated code
}
While you can look into writing your own custom converter that will use reflection to actually serialize/deserialize the internal state data (that is possibly not that hard), it can be quite brittle (class names can change, the generated code can change, the code generator code can change, and we have not even started with multiversion client support), in the end those fields a private for a reason, so I suggest looking into some set of messages the multiplayer clients will send to each other and you can turn them into iterators, classes, method calls, etc.
I'm pretty sure this is a duplicate, but I've been unable to find a fix for this after a few hours of searching/trying.
I'm not an advanced programmer, but I have a decent amount of C++ experience. I'm trying to learn C# and having trouble with very basic syntax, especially for just accessing other classes. I've been looking for simple examples for a while, and overwhelmingly, everything I find seems to use one HUGE class, wherein the main method is used, so those examples haven't been very helpful.
I want to develop a solution with multiple .cs files (one class in each), and another .cs file containing the main method that I'll use for testing. My solution is named DIVAT. I have a Dealer.cs file with the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DIVAT
{
public class Dealer
{
public List<Tuple<int, string>> deck;
Dealer()
{ // default constructor
Console.Out.WriteLine("Default constructor called. (Dealer class)");
string [] suitValue = {"c", "d", "h", "s"};
for(int i = 2; i <= 14; i++){
for(int j = 0; j <= 3; j++){
deck.Add(new Tuple<int, string>(i, suitValue[j]));
}
}
}
~Dealer()
{// destructor
Console.Out.WriteLine("Destrcutor called. (Dealer class)");
}
Tuple<int, string> Dealer.getCard(int cardNum)
{// getter
return deck[cardNum];
}
}
}
Now I'm just trying to test this in another file, Program.cs. I'm hitting 2 bugs and can't figure out why. I am having a lot of trouble just trying to initialize my Dealer class. Also, I just want to test a getter function in my Dealer class.
I use to have a lot more static and private keywords throughout, but took those out as I was hitting bugs.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DIVAT
{
class Program
{
static void Main(string[] args)
{
Dealer dealer = new Dealer();
// inaccessible due to it's protection level...
for (int i = 0; i <= 52; i++) {
Console.Out.WriteLine(dealer.getCard(i));
// does not contain a definition for getCard...
}
}
}
}
Sorry for such the basic questions, but I've been scouring the internet and trying different ways to fix this and have been unsuccessful. I feel like once I get past these few bugs, I should be able to convert a lot of my other code relatively painlessly.
Your constructor is implicitly private and since you provide zero public constructors, it cannot instantiate your class, even though the class itself is public..
You need to specify that it is public.
public Dealer() { }
As for your second question, you don't need to tell your methods that they belong to the class. They are already aware. Change your method signature like so:
public Tuple<int, string> GetCard(int cardNum)
{
// getter
return deck[cardNum];
}
Note that now the method is public and that we are scoped properly. In addition, note the PascalCasing on your method name. This is the appropriate naming convention for method names in C#.
Also, on another note, since C# is a managed language, you probably don't need your destructor.
According to this answer when code uses local variables from inside lambda methods the compiler will generate extra classes that can have name such as c__DisplayClass1. For example the following (completely useless) code:
class Program
{
static void Main()
{
try {
implMain();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
static void implMain()
{
for (int i = 0; i < 10; i++) {
invoke(() => {
Console.WriteLine(i);
throw new InvalidOperationException();
});
}
}
static void invoke(Action what)
{
what();
}
}
outputs the following call stack:
System.InvalidOperationException
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
at ConsoleApplication1.Program.implMain()
at ConsoleApplication1.Program.Main()
Note that there's c__DisplayClass2 in there which is a name of a class generated by the compiler to hold the loop variable.
According to this answer c__DisplayClass "means"
c --> anonymous method closure class ("DisplayClass")
Okay, but what does "DisplayClass" mean here?
What does this generated class "display"? In other words why is it not "MagicClass" or "GeneratedClass" or any other name?
From an answer to a related question by Eric Lippert:
The reason that a closure class is called "DisplayClass" is a bit unfortunate: this is jargon used by the debugger team to describe a class that has special behaviours when displayed in the debugger. Obviously we do not want to display "x" as a field of an impossibly-named class when you are debugging your code; rather, you want it to look like any other local variable. There is special gear in the debugger to handle doing so for this kind of display class. It probably should have been called "ClosureClass" instead, to make it easier to read disassembly.
You can get some insight from the C# compiler source as available from the SSCLI20 distribution, csharp/sccomp subdirectory. Searching the code for "display" gives most hits in the fncbind.cpp source code file. You'll see it used in code symbols as well as comments.
The comments strongly suggest that this was a term used internally by the team, possibly as far back as the design meetings. This is .NET 2.0 vintage code, there was not a lot of code rewriting going on yet. Just iterators and anonymous methods, both implemented in very similar ways. The term "display class" is offset from "user class" in the comments, a clear hint that they used the term to denote auto-generated classes. No strong hint why "display" was favored, I suspect that it might have something to do with these classes being visible in the metadata of the assembly.
Based on Reflector, DisplayClass can be translated as CompilerGeneratedClass
[CompilerGenerated]
private sealed class <>c__DisplayClass16b
{
// Fields
public MainForm <>4__this;
public object sender;
// Methods
public void <cmdADSInit_Click>b__16a()
{
ADS.Initialize();
this.<>4__this._Sender = this.sender;
this.<>4__this.SelectedObject = ADS.Instance;
}
}
In my "LuaTest" namespace I have a class called "Planet". The C# code reads like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuaInterface;
namespace LuaTest
{
public class Planet
{
public Planet(string name)
{
this.Name = name;
}
public Planet() : this("NoName") { }
public string Name
{
get;
private set;
}
public void printName()
{
Console.WriteLine("This planet's name is {0}", Name);
}
}
}
Then I built LuaTest.dll and copied this file to the same folder where my Lua script is saved. In the Lua script I wrote:
--define Path for required dlls
package.cpath = package.cpath .. ";" .. "/?.dll"
package.path = package.path .. ";" .. "/?.dll/"
require 'luanet'
luanet.load_assembly("LuaTest")
local Planet = luanet.import_type("LuaTest.Planet")
local planet = Planet("Earth")
planet.printName()
However, this piece of code does not work. Lua interpreter throws this error:
lua: dllTest.lua:7: attempt to call local 'Planet' (a nil value)
I suspect that my LuaTest assembly is not loaded at all. Could anyone point out where I did wrong? I would very much appreciate it, since I've been stuck by this problem for days.
Also it might be helpful to add that my LuaInterface.dll is the rebuilt version in .NET4.0 environment.
So I spent a LOT of time similarly. What really drove me bonkers was trying to get Enums working. Eventually I ditched my project for a very simplified console application, very similar (ironically also named 'LuaTest').
Edit: I've noted that the initial "luanet.load_assembly("LuaTest")" appears superfluous. Works with it, or surprisingly without it.
Another Edit: As in my badly edited comment below, when I removed:
print(luanet.LuaTest.Pointless)
It all stopped working (LuaTest.Pointless became nil). But adding the luanet.load_assembly("LuaTest") then makes it work. It may be that there is some sort of odd implicit load in the print or in just expressing they type. Very Strange(tm).
In any case, it seems to work for me (note: after a lot of experimentation). I don't know why yours is failing, I don't note any real difference, but here's all my code in case someone else can spot the critical difference:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuaInterface;
namespace LuaTest
{
public class Program
{
static void Main(string[] args)
{
Lua lua = new Lua();
lua.DoFile("test.lua");
}
public int some_member = 3;
}
public class Pointless
{
public enum AnEnum
{
One,
Two,
Three
};
public static string aStaticInt = "This is static.";
public double i;
public string n = "Nice";
public AnEnum oneEnumVal = AnEnum.One;
private AnEnum twoEnumVal = AnEnum.Two;
private string very;
public Pointless(string HowPointLess)
{
i = 3.13;
very = HowPointLess;
}
public class MoreInnerClass
{
public string message = "More, please!";
}
public void Compare(AnEnum inputEnum)
{
if (inputEnum == AnEnum.Three)
Console.WriteLine("Match.");
else
Console.WriteLine("Fail match.");
}
}
}
and test.lua:
luanet.load_assembly("LuaTest")
--Pointless is a class in LuaTest assembly
local Pointless = luanet.import_type("LuaTest.Pointless")
print(Pointless)
--Gives 'ProxyType(LuaTest.Pointless): 46104728
print(Pointless.aStaticInt)
--'This is static.'
--Fails if not static, as we expect
--Instantiate a 'Pointless'.
local p = Pointless("Very")
print(p)
--Gives 'LuaTest.Pointless: 12289376'
--Now we can get at the items inside the Pointless
--class (well, this instance, anyway).
local e = p.AnEnum;
print(e)
--ProxyType(LuaTest.Pointless+AnEnum): 23452342
--I guess the + must designate that it is a type?
print(p.i)
--3.14
print(p.oneEnumVal)
--Gives 'One: 0'
print(p.twoEnumVal)
--Gives 'twoEnumVal'... private
--behaves very differently.
print(e.Two:ToString())
--Gives 'Two'
local more = p.MoreInnerClass()
print(more.message)
--'More, Please!'
--create an enum value here in the script,
--pass it back for a comparison to
--the enum.
local anotherEnumVal = p.AnEnum.Three
p:Compare(anotherEnumVal)
--outputs 'Match'
Having spent the last several days working on a project that required this exact functionality from LuaInterface, I stumbled across a piece of Lua code that turned out to be the perfect solution (see Reference 1). Whilst searching for this solution, I noticed this question and figured I'd drop my two cents in.
To apply this solution, I merely run the CLRPackage code while initializing my LuaInterface Lua object. However, the require statement works just as well.
The code provided in reference 1 allows the use of import statements, similar to C# using statements. Once an assembly is imported, its members are accessible in the global namespace. The import statement eliminates the need to use load_assembly or import_type (except in situations in which you need to use members of the same name from different assemblies. In this scenario, import_type would be used similar to C# using NewTypeName = Assembly.OldTypeName).
import "LuaTest"
planet = Planet("Earth")
planet:printName()
This package also works great with enums!
Further information regarding the use of this package may be found at Reference 2.
Hope this helps!
Reference 1: https://github.com/stevedonovan/MonoLuaInterface/blob/master/bin/lua/CLRPackage.lua
Reference 2: http://penlight.luaforge.net/project-pages/penlight/packages/LuaInterface/
I spent some time in binding C# dll to lua. Your posts were helpful but something was missing. The following solution should work:
(Make sure to change your compiler to .NET Framework 3.5 or lower!)
Planet.dll:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Planets
{
public class Planet
{
private string name;
public string Name
{
get { return name; }
set { this.name = value; }
}
private float diameter;
public float Diameter
{
get { return diameter; }
set { this.diameter = value; }
}
private int cntContinents;
public int CntContinents
{
get { return cntContinents; }
set { this.cntContinents = value; }
}
public Planet()
{
Console.WriteLine("Constructor 1");
this.name = "nameless";
this.diameter = 0;
this.cntContinents = 0;
}
public Planet(string n, float d, int k)
{
Console.WriteLine("Constructor 2");
this.name = n;
this.diameter = d;
this.cntContinents = k;
}
public void testMethod()
{
Console.WriteLine("This is a Test!");
}
}
}
Use the code above, paste it into your class library project and compile it with .NET smaller or equal 3.5.
The location of the generated DLL needs to be known by the lua enviroment. Paste it e.g at "clibs"-folder or another well known lua system path. Then try to use the following lua example. It should work.
Test1.lua: (Option 1 with "import" from CLRPackage)
require "luanet"
require "CLRPackage"
import "Planet"
local PlanetClass = luanet.import_type("Planets.Planet")
print(PlanetClass)
local PlanetObject1 = PlanetClass()
print(PlanetObject1)
local PlanetObject2 = PlanetClass("Earth",6371.00*2,7)
print(PlanetObject1.Name)
PlanetObject1.Name = 'Mars'
print(PlanetObject1.Name)
print( "Planet " ..
PlanetObject2.Name ..
" is my home planet. Its diameter is round about " ..
PlanetObject2.Diameter .. "km." ..
" Our neighour is " ..
PlanetObject1.Name)
Test2.lua: (Option 2 with "load_assembly")
require "luanet"
require "CLRPackage"
luanet.load_assembly("Planet")
local PlanetClass = luanet.import_type("Planets.Planet")
print(PlanetClass)
local PlanetObject1 = PlanetClass()
print(PlanetObject1)
local PlanetObject2 = PlanetClass("Earth",6371.00*2,7)
print(PlanetObject1.Name)
PlanetObject1.Name = 'Mars'
print(PlanetObject1.Name)
print( "Planet " ..
PlanetObject2.Name ..
" is my home planet. Its diameter is round about " ..
PlanetObject2.Diameter .. "km." ..
" Our neighour is " ..
PlanetObject1.Name)
In both cases the console output will look like this:
ProxyType(Planets.Planet): 18643596
Constructor 1
Planets.Planet: 33574638
Constructor 2
nameless
Mars
Planet Earth is my home planet. Its diameter is round about 12742km. Our neighbour is Mars
I hope its helps some of you.
Edit 1:
by the way, a method call from lua looks like this:
PlanetObject1:testMethod()
PlanetObject2:testMethod()
Edit 2:
I found different dll's whitch needed to be handled differently. One needed the "import"-function and another needed the "load_assembly"-function. Keep that maybe in mind!
I am new to StyleCop, and I need to implement own coding standarts for the place I work. I am using VS2005 and cannot debug it. Upgrading to VS2008/2010 is not an option for us now.
I wonder many things:
1) How can I identify the methods parameters? I tried the below but do not know where to go, SDK documentation is not really helpful.
private bool VisitElement(CsElement element, CsElement parentElement, object context)
{
if (element.ElementType == ElementType.Method)
{
...
2) How can I find out that a declaration do not follow an assignment? Ex.given.
int i; // Wrong, give warning
int i = 0; // True usage
3) How can I find out that a document does not contain only 1 namespace or only 1 class inside it and how can I get their identifiers (names)?
True:
namespace Hello
{
class P{
}
}
-
Wrong:
namespace Hi {
class C {
}
class E {
}
}
namespace Ho {
class D {
}
}
4) How can I find out function calls and find out where to? (i.e. Blocking a call to specific function)
For #1, take a look at the Microsoft.StyleCop.CSharp.ReadabilityRules.CheckMethodParameters method implementation (either in Reflector or at http://stylecop.codeplex.com/SourceControl/changeset/view/64d44becb157#Project%2fSrc%2fAddIns%2fCSharp%2fAnalyzers%2fReadabilityRules.MethodParameters.cs).
For #2, something like the following should do the trick:
private bool VisitExpression(Expression expression, Expression parentExpression, Statement parentStatement, CsElement parentElement, object context)
{
if (expression.ExpressionType == ExpressionType.VariableDeclarator)
{
VariableDeclaratorExpression declaratorExpression = (VariableDeclaratorExpression)expression;
if (declaratorExpression.Initializer == null)
{
this.AddViolation(parentElement, expression.LineNumber, "YourRule", declaratorExpression.Identifier.Text);
}
}
return true;
}
The existing SA1402 (FileMayOnlyContainASingleClass) and SA1403 (FileMayOnlyContainASingleNamespace) rules should take care of #3. If they don't work for your scenario, please specify what you would like a custom rule to do differently.
#4 should be an FxCop rule, not a StyleCop rule since it has nothing to do with source code style.