Consider the following C# program:
using System;
using System.Diagnostics;
namespace Test
{
class MainClass
{
public static void Main (string[] args)
{
Debug.Assert(false);
Debug.Fail("fail!");
Console.WriteLine ("Hello World!");
}
}
}
When compiling this using:
dmcs -debug -d:DEBUG Main.cs
and then running it with:
mono --debug Main.exe
the assertion and fail seem to be ignored. The output is just:
Hello World!
I checked other related questions on StackOverflow, but I could not find a solution. In particular the solution give in Mono - Debug.Assert does not work does not work. (UPDATE: the updated solution does work, see below comments.)
I use Mono 2.10.5-1 on Ubuntu 11.10.
C# on mono - http://ebsteblog.wordpress.com/2009/05/06/debugassert-and-mono/
Excerpt from the article:
...if you create a .config file for your app and set the assertuienabled attribute to true, you get the same dialog as with .NET... File app.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.diagnostics>
<assert assertuienabled="true" />
</system.diagnostics>
</configuration>
Old answer: C++ comment if you did not specify -define DEBUG on command line/compile options.
For debug add
#define DEBUG
at the beginning of the code or
#define TRACE
for trace.
See the solution here: http://lists.ximian.com/pipermail/mono-list/2006-December/033774.html
p.s: I tried this with C++ not C#. This may not work for C#.
You can use the xml configuration, or you can place it under the control of your program by adding a trace listener at runtime:
var tl = new System.Diagnostics.ConsoleTraceListener();
System.Diagnostics.Debug.Listeners.Add ( tl );
This has the added advantage of you being able to enable it after the program has started.
Related
I've installed Splashkit SDK and .Net Core SDK following the instructions below.
https://splashkit.io/articles/installation/mac/step-2/
Im using C#.net framework by following the above instructions from the website.
Below is the code
using System;
using SplashKitSDK;
namespace test
{
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World!");
Window w = new Window("My First Program", 200, 100);
w.DrawText("Hello, World", Color.Black, 10, 45);
w.Refresh(60);
SplashKit.Delay(5000);
}
}
}
When I run the above code the Hello World prints to the console but the window object is not working. Screeshot attached with error code.
I tried adding as much information as I could, If theres anything i've missed please let me know.
I tried copying the shared library which is native to the usr/local/library but that did not work, I also tried what the error message has said, I'm not very expereinced so I might be doing it worng, I'm not sure.
I'm expecting a window to open with the hello world.
Just switched to VS2022, created new project and see this:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Where is all other stuff? Why is that by default now?
Click the link. It redirects to https://learn.microsoft.com/nl-nl/dotnet/core/tutorials/top-level-templates. It has a paragraph stating:
If you want to use the old templates, see the Use the old program style section.
That section mentions that this is the new default. To circumvent it, create a .NET 5-targeting application, and modify your project file:
- <TargetFramework>net5.0</TargetFramework>
+ <TargetFramework>net6.0</TargetFramework>
A workaround I guess would be to create a custom project template.
If you are using Visual Studio, you can install the Classic Console Template
https://marketplace.visualstudio.com/items?itemName=Doomdied.ClassicConsole1
It add old classic console back, then you can forgot the new one.
You can access the args through a special variable with that name in a top level statement class file:
if (args.Length > 0)
{
foreach (var arg in args)
{
Console.WriteLine($"Argument={arg}");
}
}
else
{
Console.WriteLine("No arguments");
}
Similarly, you just return an int to set the exit code:
string? s = Console.ReadLine();
int returnValue = int.Parse(s ?? "-1");
return returnValue;
See:
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements
As to why, there has been a push to clean up the source files from needless whitespace, masses of curly braces, long lists of imports at the top of each file and the explicit namespace declaration, where most everyone syncs the namespaces with the assembly name and solution folder anyway.
It's been a thorn in the eye of many that simple things in c# need 10s of lines of code where they are a single line in node or python or ruby. It's just not productive. Same for Razor templates and Razor files. You just need an IDE to do she right thing. With these changes it should become much easier to be productive from the GitHub, even if you're not using Visual Studio.
Visual Studio 2022 with .NET 6 uses a new template when creating a C# console app. The new template reduces the amount of boilerplate code necessary to write a simple C# program. I believe this change was meant to benefit beginning programmers and those who are new to C#.
New style:
Statements in Program.cs that appear outside of any function are automatically placed in Main().
Function declarations are moved outside Main() and made static.
A number of using statements are implicitly added for common namespaces like System, System.IO, System.Linq, etc.
Example:
// New style
Console.WriteLine("Code in Main()");
Test();
void Test()
{
Console.WriteLine("Test");
}
is roughly equivalent to:
// Old style
using System;
namespace MyApp
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Code in Main()");
Test();
}
static void Test()
{
Console.WriteLine("Test");
}
}
}
There is nothing stopping you from using the old style. You can copy and paste the old-style code above into Program.cs, and it will run just fine.
There is an option now, to disable top-level statements:
I just tried it and it produces an old-style project. :-)
You also don't loose file-scoped namespaces, they still work.
The "other stuff" is all there; it's just a new convention. It isn't obvious as you might use to get things in C# but this is the new way. And of course, you can use the old style with Main(string args) by selecting Do no use top-level statements checkbox when creating the project in Visual Studio or employ the --use-program-main option on the command line, like this:
dotnet new console --use-program-main
As for the magic of accessing the command line arguments with this new style, see my answer here.
In my web.config I have:
<system.diagnostics>
<switches>
<add name="logLevelSwitch" value="1" />
</switches>
</system.diagnostics>
Is there a way that I could call, for example:
System.Diagnostics.TraceSwitch["logLevelSwitch"]to get the current value?
Once you've defined the switch value in your web.config file, it's easy to get this value from your application by creating a TraceSwitch with the same name:
private static TraceSwitch logSwitch = new TraceSwitch("logLevelSwitch",
"This is your logLevelSwitch in the config file");
public static void Main(string[] args)
{
// you can get its properties value then:
Console.WriteLine("Trace switch {0} is configured as {1}",
logSwitch.DisplayName,
logSwitch.Level.ToString());
// and you can use it like this:
if (logSwitch.TraceError)
Trace.WriteLine("This is an error");
// or like this also:
Trace.WriteLineIf(logSwitch.TraceWarning, "This is a warning");
}
Moreover, for this to work, according to the documentation:
You must enable tracing or debugging to use a switch. The following
syntax is compiler specific. If you use compilers other than C# or
Visual Basic, refer to the documentation for your compiler.
To enabledebugging in C#, add the /d:DEBUG flag to the compiler command line
when you compile your code, or you can add #define DEBUG to the top of
your file. In Visual Basic, add the /d:DEBUG=True flag to the compiler
command line.
To enable tracing using in C#, add the /d:TRACE flag to
the compiler command line when you compile your code, or add #define TRACE to the top of your file. In Visual Basic, add the /d:TRACE=True
flag to the compiler command line.
I'm trying to get my linux Gtk# application working on Windows. When I try to run it, I get this error message:
Unhandled Exception: GLib.GException:
Unhandled tag: 'requires'
at Gtk.Builder.AddFromFile(String
filename)
at Interface.MainWindow..ctor()
at [My Project Name].MainClass.Main(String[]
args) in c:\Path\To\Main.cs:line 10
It seems to be happening when trying to build the interface from my Glade file. I've checked and the path to the glade file is correct. What might be going wrong?
Here is some code to reproduce the problem:
using System;
using Gtk;
namespace TestGtk {
class MainClass {
public static void Main (string[] args)
{
Application.Init();
string gladefile = #"C:\path\to\gladefile.glade";
Builder builder = new Builder();
builder.AddFromFile(gladefile);
Application.Run();
}
}
}
Strange... I don't know why on windows GTK# does not support requires. Anyway I'd try to remove the <requires ... /> tag from gladefile.glade.
This most likely means that your Glade file is corrupt or has got some weirdness in it.
You're using GtkBuilder to load GladeXML files. GtkBuilder has different XML format, incompatible with GladeXML (it more generic). If you use glade-3 to design your UI, you have an option to save as GtkBuilder XML or GladeXML. Also, glade has utility called gtk-builder-convert that you can use to convert GladeXML to GtkBuilder XML.
So, there are two options:
Use glade-3 and save your UI in GtkBuilder format
Use gtk-builder-convert utility
Glade is for GTK 3.x and your system is probably on GTK 4.x.
I had a similar issue when the version was not specified in a Python app using a .glade file, and upon running it would show:
Use gi.require_version('Gtk', '4.0') before import to ensure that the right version gets loaded.
It worked prior to an Ubuntu update last I ran if. After adding
import gi
gi.require_version("Gtk", "3.0")
It works.
A similar issue was noted in a Haskell app. I am not sure how one changes the reference to GTK3 on C#.
The trusty old preprocessor directive in C# appear to work great when I write:
#if DEBUG
...
(Some code)
...
#endif
However, attributes enclosed in the conditional block appear to continue to get processed and I get errors indicating such. For instance, surrounding an [AssemblyVersion(...)] within the conditional block appears to have no affect.
I can go into the details as to why we want to conditionally ignore the [AssemblyVersion(..)], but it's irrelevant. Any ideas?
This works correctly for me. In my AssemblyInfo.cs file, I have the following:
#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif
Looking at the compiled assembly in Reflector, I see the correct attributes.
You should make sure that your DEBUG symbol is only defined in the project properties and not any where else in your code as an actual #define DEBUG instruction. If you have it defined directly in code it will only be in effect for that file, not the entire project. Defining it in the project properties will cause it be in effect for the entire project.
I figured it out! There was a key piece of information I neglected to mention: that it was a Workflow project (Guid {14822709-B5A1-4724-98CA-57A101D1B079}). It turns out that there is a bug with the workflow project type, specifically the Workflow.Targets file that is included in the build file.
It appears that the preprocessor acts as though the DEBUG constant is defined. You can repro the issue by creating a workflow project and adding this to the AssemblyInfo file:
#if DEBUG
[assembly: AssemblyFileVersion("1.0.0.0")]
#endif
Then try a release build.
I filed this with MS: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=466440
Best regards!
-Sean
Are you sure you're not building in release mode?
simpler - you can tag your debug function(s) with the metadata tag [Conditional]:
#define DEBUG1
...
public static void PrintText1(string txt) {
Console.Write("This is PrintText2\n");
}
[Conditional("DEBUG1")]
public static void PrintText2(string txt) {
Console.Write("This is PrintText2\n");
}
[STAThread]
static void Main(string[] args) {
PrintText1("This is the unconditional method");
PrintText2("This function will be called only if 'DEBUG1' is defined");
}
try it!
Also, what I noticed is that #define only exists within the context of the file it is defined, ex calling PrintText2 from another file, where debug is not defined, will not execute. This also works the other way around:
[Conditional("DEBUG1")]
public static void ConditionedPrint(string txt) {
Console.Write("This is PrintText2\n");
}
public static void UnconditionedPrint(string txt) {
ConditionedFunc(txt);
}
UnconditionedFunc will print "This is PrintText2\n" iff (if and only if) #define DEBUG1 was defined in this file, regardless of the other files.
There is also System.Diagnostics.Debug, I'm not sure what it does though.
To follow up #yoyoyoyosef comment answer, you need to check the Properties page of your Project.
You will see in the Build menu, under the General heading, make sure the "Define DEBUG constant" checkbox is not checked.
This value changes based upon the "Configuration" choice (dropdown) at the top of the Build menu.