Defining custom Mono "using" directive like for Java "import" - c#

To avoid repetitive definitions, I am trying to move internal function prototypes from the class One into a C# using My.Class.One directive (like import My.Class.One in Java).
In Java, this would change this code:
public class One {
public static void func1();
public static void func2();
public static int main(String[] args) { ... }
}
...into that code split into different files:
import My.Include;
public class One {
public static int Main(String[] args) { ... }
}
------------------------->8--------------------------------
package Include;
public class My {
public static void func1();
public static void func2();
...
}
After learning that Java 'packages' are named 'namespaces' in C# I came up with the following C# code which fails to compile (mcs One.cs My_include.cs -out:One.exe) with the error:
> "error CS0103: The name `func1' does not exist in the current context"
using System;
using My.Include;
public class One {
public static int Main(String[] args) { return funct1(); }
}
------------------------->8--------------------------------
using System;
namespace My {
namespace Include {
public class functions {
public static void func1();
public static void func2();
...
}
}
}
I tried many different naming conventions but I still get the same error. Can you tell me what I do wrong?

It looks like you want a partial class, so your main class file would look like:
// File: One.cs
using System;
public class One
{
static void Main()
{
// Your Main method here
}
}
And you would have a second file which looks like:
// File: One.Externs.cs
using System;
public partial class One
{
extern static void func1();
extern static void func2();
}
At compile-time, these two (or more) files are automatically combined to a single class by the compiler. This gives you the separation you appear to be looking for, but keeps the relevant definitions within the correct scopes.
The using directive is only partially synonymous to java's import directive - in C# using only provides a shortcut into a namespace whereas you're used to referring to a class or partial class with import.

Related

How to split C# (Console application) classes into different files

namespace APIproject
{
public class ApiCallResponse //class1
class Program //class2
}
I have two classes in my code and both are in the same file name Program.cs.
I want to shift my ApiCallResponse class into another file like Program1.cs
And then I want to call the new file Program1.cs into Program.cs to access that class.
How can I do that?
If you want to have a class in a separate file, which is actually a common practice, you need to add a class file (*.cs) and write your code there.
After this, you need to reference a namespace that contains your class and then use your class as usual:
Program.cs:
using MySolution.Responses; //This is how you can connect different classes.
namespace MySolution
{
public class Program
{
public static void Main(string[] args)
{
var response = new ApiCallResponse();
}
}
}
../Responses/ApiCallResponse.cs:
namespace MySolution.Responses
{
public class ApiCallResponse
{
public ApiCallResponse()
{
}
}
}

How to define a method following top-level statements

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");
}

How can I call a function from C# app in a C++/CLI DLL?

I've written a simple C++/CLI DLL that has 2 public static methods:
namespace GetMscVerLib
{
public ref class CGetMscVer
{
static System::Int32 GetCompilerVersion ();
static System::Int32 GetCompilerFullVersion ();
};
}
I'm trying to call these methods from a C# console app in the same solution but the compiler doesn't recognize the methods and shows an error that says that the methods don't "exist in the current context":
namespace Get_MSC_VER
{
class Program
{
static void Main (string[] args)
{
Int32 i32CompilerVersion = CGetMscVer.GetCompilerVersion ();
Int32 i32CompilerFullVersion = CGetMscVer.GetCompilerFullVersion ();
}
}
}
What is the correct syntax? (online searches have produced pages of irrelevant links with some of the search keywords, assuming DllImport or COM). This seems like it should be quite a simple matter but finding it is not.
Thanks
First you need build your C++ program, you will get dll. Then you should create method with the same return value and add extern key word add DllImport attribute to your method. In your example method will look like this:
public class Program
{
static void Main(string[] args)
{
var version = GetCompilerVersion();
var fullVersion = GetCompilerFullVersion();
}
[DllImport("yourDllName.dll")]
public static extern int GetCompilerVersion();
[DllImport("yourDllName.dll")]
public static extern int GetCompilerFullVersion();
}
This should work. Because the methods are private by default c# wont allow you to access them.
namespace GetMscVerLib
{
public ref class CGetMscVer
{
public:
static System::Int32 GetCompilerVersion ();
static System::Int32 GetCompilerFullVersion ();
};
}
Another way, keeping everything static.
// C++/CLI DLL
namespace GetMscVerLib
{
public ref class CGetMscVer abstract sealed
{
public:
static System::Int32 GetCompilerVersion();
};
}
// C# assembly that references the C/C++ DLL
namespace Get_MSC_VER
{
class Program
{
static void Main (string[] args)
{
Int32 i32CompilerVersion = GetMscVerLib.CGetMscVer.GetCompilerVersion();
}
}
}

C# 7 Local Functions: are attributes / aspects allowed?

C# 7 introduced local functions (which is great!). Suppose I have the following code:
using System;
using PostSharp.Aspects;
namespace AspectCS7
{
class Program
{
private static void Main()
{
[MyAspect]
void LocalFunction()
{
Console.WriteLine("Hello Aspect!");
}
LocalFunction();
}
}
[Serializable]
public class MyAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("Entering Aspect");
}
}
}
This code shows compile-time errors. Is it possible to apply attributes to local functions?
Attributes were allowed on local functions at one point. There are some examples on the web of local functions using attributes, however they're not allowed anymore.
Update:
Here is an ongoing discussion on this topic: https://github.com/dotnet/csharplang/issues/794.

Namespace issue with period

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();
}
}
}

Categories