So I am new to C# and done some researching on how to do this but I still don't get it.
I have 2 files, file foo and file bar. File foo is my main file and I want to use a function from inside bar inside foo. The function's purpose is not important because I am just playing around for now. As of now it is an alternative method to print text into the console. I am getting this error message when I try to execute the command csc foo.cs:
foo.cs(9,13): error CS0103: The name 'message' does not exist in the current context
foo.cs
using System;
namespace main
{
class program
{
static void Main(string[] args)
{
message.print("Hello World!"); //line 9
Console.ReadLine();
}
}
}
bar.cs
using System;
namespace main
{
public class message
{
public void print(string Message)
{
Console.WriteLine(Message);
}
}
}
any help would be much appreciated
ALSO: note that both files are in the same directory and both classes are in the same namespace.
Because screenshot was
requested
using System;
namespace main
{
class program
{
static void Main(string[] args)
{
message m=new message();
m.print("Hello World!"); //line 9
Console.ReadLine();
}
}
}
You should create class instance, and then call the method of that variable.
Not that class names should start with capital first letter.
Try this:
using System;
public class Program
{
public static void Main()
{
Message msg = new Message();
msg.print("Hello World!"); //line 9
Console.ReadLine();
}
public class Message
{
public void print(string Message)
{
Console.WriteLine(Message);
}
}
}
Here is a working solution. snippet
Alternatively to the other answers, print could be static. Also note that the C# convention is that file, namespace, class and method names are in upper camel case, while parameters are in lower camel case. Another convention is to name the file the same as the class.
Program.cs
using System;
namespace Main
{
class Program
{
static void Main(string[] args)
{
Message.Print("Hello World!");
Console.ReadLine();
}
}
}
Message.cs
using System;
namespace Main
{
public class Message
{
public static void Print(string message)
{
Console.WriteLine(message);
}
}
}
Edit:
Earlier I wrote that Main must be public, because .NET Fiddle required it. However, this is apparently not generally the case.
OK. I found an answer. There were many problems but at the end I had to change up the command I was using.
At first I was using csc foo.cs
then I changed it to csc foo.cs bar.cs
As of yet I am unsure of exactly why but I will provide updates when I figure it out.
https://www.c-sharpcorner.com/UploadFile/puranindia/CommandLineCompilerOptions11082009234932PM/CommandLineCompilerOptions.aspx
There is a documentation for options for the csc command.
Related
I recently updated Visual Studio and found out about this new feature (to me it is new) of top-level statements.
As I understand it, the compiler completes the definitions for the Program class and Main method, without you having to explicitly type it up.
This is useful, but I'm having trouble when defining a new method. I would like a method in the Program class. And call this with a top-level statement. Here is some example code:
Console.WriteLine("toplevel");
ThisShouldBeAMethodOfProgramClass();
public static void ThisShouldBeAMethodOfProgramClass()
{
Console.WriteLine("Static in Program class");
}
This is giving me build errors, because the public static modifiers are not valid. I think it interprets this as a local function in Main. I can remove the modifiers, but this is just example code, my real code has more methods and classes.
How can I do this? Should I not use top-level for this?
I would like this to effectively be the same as:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("toplevel");
ThisShouldBeAMethodOfProgramClass();
}
public static void ThisShouldBeAMethodOfProgramClass()
{
Console.WriteLine("Static in Program class");
}
}
You can keep using top-level statements and append additional members with a partial Program class.
using System;
Console.WriteLine("toplevel");
ThisShouldBeAMethodOfProgramClass();
public static partial class Program
{
public static void ThisShouldBeAMethodOfProgramClass()
{
Console.WriteLine("Static in Program class");
}
}
Or just remove the access modifier: method without access modifier
using System;
Console.WriteLine("toplevel");
ThisShouldBeAMethodOfProgramClass();
static void ThisShouldBeAMethodOfProgramClass()
{
Console.WriteLine("Static in Program class");
}
the C# harmony documentation: https://github.com/pardeike/Harmony/wiki/Prioritiy-annotations
my question is that not able to run the C# harmony example successfully
the postfix annotation didn't get injection log printed as expected after Class and method get patched that i didn't see "injection logs" get printed.
c# code example below. Can someone help me find the issue
you may paste into https://dotnetfiddle.net/ to debug it.
using System;
using System.Collections.Generic;
using System.Reflection;
using Harmony;
public class Program
{
public static void Main()
{
var harmony = HarmonyInstance.Create("net.example.plugin");
harmony.PatchAll(Assembly.GetExecutingAssembly());
Program p = new Program();
p.Bar();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Program), "Bar")]
public static void Postfix_Bar(){
Console.WriteLine("postfix Bar log"); // this never gets printed as expected.
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Program), "Foo")]
public static void Postfix_Foo(ref string res){ //however, this gets error res could not be found. https://github.com/pardeike/Harmony/wiki/Prioritiy-annotations
Console.WriteLine("postfix Foo log");
res = "new value";
}
public void Bar() {
Console.WriteLine("Hello World !!! ");
}
static string Foo()
{
return "secret";
}
}
The main problem is that PatchAll() looks for classes that have at least on [HarmonyPatch] annotation. Your patches are in the class Program which does not have that annotations. This is the main problem in your example.
Solution: either annotate your Program class like this:
[HarmonyPatch]
public class Program
{
}
or create a new class that has that annotation.
The second problem I can see is that Postfix_Foo(ref string res) uses res which does not follow the documented standard for naming patch arguments. It can either be the name of an argument that the original method has (it has no arguments) or refer to the result, which requires it to be named __result.
The comment about priority annotations is misplaced too because they only apply to multiple patches to the same original method.
Finally, you call Bar() after patching which means that Foo is never called - not sure if that’s intended.
Okay, so working on learning some C#. Great language, love working with it in general, but I'm not understanding how to get over this lack of utility classes. In essence, I want to set up a general utilities class that can be contained in a folder and used for any project simply by doing a "using namespace Globals/Utilities/etc." command. In essence:
using System;
namespace Globals {
public static class Commands {
public static void WaitForReturn() {
Console.WriteLine("Press Enter to continue.");
Console.ReadLine();
}
}
}
Similar to the above, such that in any other class I can call the functions by including it as a preprocessing directive.
using System;
using Globals;
namespace RectangleDemo {
<rectangle definition here>
class Demo {
static void Main(string[] args) {
Rectangle r = new Rectangle();
Rectangle s = new Rectangle(5, 6);
r.Display();
s.Display();
WaitForReturn();
}
}
}
As it is, I'm trying to simply compile my 'utility' class (with more than what is listed above) to check for errors, but it's just telling me that it can't compile it because there's no main method. Any suggestions?
(Yes I'm aware I have a java coding style, I'm okay with that!)
With C#6 you can import static methods so you can end up with the following coding style:
using System;
using static Globals.Commands;
namespace MyConsole
{
internal class Program
{
private static void Main(string[] args)
{
WaitForReturn();
}
}
}
namespace Globals
{
public static class Commands
{
public static void WaitForReturn()
{
Console.WriteLine("Press Enter to continue.");
Console.ReadLine();
}
}
}
And as suggested by Tim, if you don't want a main entry point, use a Class Library project instead of a Console Application.
C# doesn't work the way you're expecting. There is no relationship between importing namespaces/classes and files so doing using Globals; does not translate to file content inclusion à la C/C++ (i.e. not the same as #include "Globals.cs").
On the command line, the C# compiler accepts the list of files that make up your sources:
csc Demo.cs Globals.cs
If you are using an IDE like Visual Studio, you would link the Globals.cs into your project. And by link, I mean more like a symbolic link (though it is not in actual fact) than static linking via a linker as you would have typically in a C/C++ setup.
So to make your scenario of “inclusion of common code” work, you need to compile by simply always adding Globals.cs to the list of C# files making up your project (supplied to the compiler on the command line or added to your project in IDE) and then using a static import:
using System;
using static Globals.Commands; // <-- import statically allows methods to be
// used without class name qualification
namespace RectangleDemo {
// <rectangle definition here>
class Demo {
static void Main(string[] args) {
Rectangle r = new Rectangle();
Rectangle s = new Rectangle(5, 6);
r.Display();
s.Display();
WaitForReturn();
}
}
}
Is it possible to define a class (not interface) outside of any namespace?
Ran a test and yes you can. Here's my code built off of a Console App:
using System;
using System.Text;
namespace With_Console_App
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("This will output something: ");
Console.ReadLine();
some.Print();
Console.ReadLine();
}
}
}
class some
{
public static void Print()
{
Console.WriteLine("something");
}
}
Yes, you can define a class outside of a namespace. Per juharr it ends up in the default global namespace.
I have a class:
namespace FooIOS
{
public class Foo
{
public static void doThis() {...}
}
}
And this works:
using FooIOS;
namespace Sample.iOS
{
public void method () {
Foo.doThis();
}
}
However, this does not work the same way when I change the namespace to insert a period:
namespace Foo.iOS
{
public class Foo
{
public static void doThis() {...}
}
}
using Foo.iOS;
namespace Sample.iOS
{
public void method () {
// Compilation error
Foo.doThis();
// Compilation error
Foo.iOS.doThis()
// This works but I can't have it that long and complicated (I'm writing an API call)
Foo.iOS.Foo.doThis();
}
}
I'm pretty inexperienced with C# and I'm wondering if there's any way to use the period in the namespace and not deal with the complicated call.
namespace Foo.iOS
{
public class Foo
{
public static void doThis() {...}
}
}
Your namespace name is Foo.iOS, class name is Foo, static method name is doThis(). The fully qualified path to access that method is NAMESPACE.CLASS.METHOD_NAME, so it becomes:
Foo.iOS.Foo.doThis();
Here is nothing wrong with C#, but with the naming you use.
From this a couple of suggestions:
try to no use . inside names of the namespace, as this introduces confusion
try to not name namespace as the class inside it, as this introduces confusion.
I'm pretty inexperienced with C# and I'm wondering if there's any way
to use the period in the namespace and not deal with the complicated
call.
Short answer is: name your namespaces, classes and member functions in a way, that it does not look complicated to you and to others.
EDIT
Consider that you can use also Namespace Alias.
For example:
using IOS = Foo.iOS;
...
IOS.Foo.doThis();
But as I said before, it's better to avoid . in namespace name at first place.
Bring the using Foo.iOS; statement inside the namespace Sample.iOS namespace block, like shown below, then you will be able to call doThis() like in your 1st attempt Foo.doThis(); that was previously giving you a compile error.
namespace Sample.iOS
{
using Foo.iOS;
public void method () {
// this works
Foo.doThis();
}
}
Related reading: Inside or Outside? by Eric Lippert on MSDN.
Fully working Code sample:
Create a new Console App in Visual Studio, and then in the Program.cs class, delete all lines, paste the following, do a compile and then run.
using System;
namespace Foo.iOS
{
public class Foo
{
public static void doThis() { Console.Write("Inside doThis");}
}
}
namespace Sample.iOS
{
using Foo.iOS;
class Program
{
static void Main(string[] args)
{
method();
Console.ReadKey();
}
public static void method ()
{
// works fine
Foo.doThis();
}
}
}