I have the follwoing code which I don't understand where is my mistake?
Here's the code:
using System;
using System.Collections;
namespace ConsoleApplication5
{
static void Main(string[] args)
{
class Program
{
public class Animal
{
public virtual void Greet()
{
Console.WriteLine("Hello, I'm some sort of animal!");
}
}
public class Dog : Animal
{
public override void Greet()
{
Console.WriteLine("Hello, I'm a dog!");
}
}
}
It doesn't get compiled, I get the following errors:
On Line 24 Type or namespace definition, or end-of-file expected
and on Line 6 } is expected
I don't understand what did I do wrong, can you help me?
Thanks.
I compiled this in Visual Studio 2015, if it matters.
BTW, I got part of this code from this tutorial:
http://csharp.net-tutorials.com/classes/inheritance/
I believe you have a confusion about scopes. You defined a class in a method which is not applicable, you should define classes under namespace scope.
It should be this way (This is a pseudo code)
namespace YourNamespace
...class Program
.... public class animal
.... public class dog : animal
.... static void main
You cannot define a class within a method body, which is what happens here:
static void Main(string[] args)
{
class Program
{
Instead you need to place the code for your Main() method within the Program class:
class Program
{ // This brace marks the beginning of the Program class
static void Main(string[] args) // This is a method defined WITHIN Program class
{ // The brace marks the beginning of the Main method
....
} // This brace marks the end of the Main method
} // This brace closes the Program class
Related
I was reading about virtual method tables on wikipedia and I stumbled upon
Whenever a class defines a virtual function (or method), most compilers add a hidden member variable to the class which points to an array of pointers to (virtual) functions called the virtual method table (VMT or Vtable).
However, when I decompile my test code I don't find any member variable in the IL.
I am using latest version of Roslyn to compile (2.6.0).
Here is my test code:
namespace ConsoleApp1
{
using System;
internal class Program
{
private static void Main(string[] args)
{
var a = new Base();
var b = new Derived();
a.Say();
b.Say();
}
}
public class Base
{
public virtual void Say()
{
Console.WriteLine($"{this.GetType()}");
}
}
public class Derived : Base
{
public override void Say()
{
Console.WriteLine($"{this.GetType()}");
}
}
}
I suppose I am misunderstanding something here, could you help me what it is?
I tried to move implementation to other file and got Error in Form1.cs "OpenPort doesn't exist in the curent context"
Any suggestions, please?
Form1.cs
namespace MyApp
{
void Form1Load(object sender, EventArgs e)
{
OpenPort();
}
}
Port.cs
namespace MyApp
{
public static void OpenPort();
}
First of all you can't declare methods or properties directly in a namespace. You have to declare a class first, in which you write your methods. Then, if you want to "spread" the same class in different files, you ought to add the partial keyword.
Form1.cs
namespace MyApp
{
public partial class MyClass
{
public void Form1Load(object sender, EventArgs e)
{
OpenPort();
}
}
}
Port.cs
namespace MyApp
{
public partial class MyClass
{
public static void OpenPort()
{
// your implementation here
}
}
}
Think of a namespace like a container. Just like any other container you can put stuff in it. An advantage of namespaces is that they can group functionality together without you needing to put everything in the same file - of particular use when programs get large. Namespaces are also a way of keeping names separate. Think of roads - both London Road and High Street may both have a number 18 but 18 London Road and 18 High Street are different and distinguishable.
For example, MyNamespace contains MyClass and MyClass contains MyMethod
namespace MyNamespace
{
class MyClass
{
void MyMethod() {}
}
}
To use MyMethod from another namespace you need to add a using statement for MyNamespace.
Taking this a step further imagine MyOtherNamespace contains MyClass and MyClass contains MyMethod
MyOtherNamespace also contains MyClass and MyClass also contains MyMethod
namespace MyOtherNamespace
{
class MyClass
{
void MyMethod() {}
}
}
As before, to use MyMethod from another namespace you need to add a using statement for MyOtherNamespace.
If you want to use MyMethod from both MyNamespace and MyOtherNamespace you must tell your program which one to use by adding the Namespace name to the call like this
MyNamespace.MyClass.MyMethod();
MyOtherNamespace.MyClass.MyMethod();
The same rule applies if you've got multiple classes with the same method in the same namespace - the difference being you don't need to include the namespace
MyFirstClass.MyMethod();
MySecondClass.MyMethod();
On a related note, you can also split a class between multiple files using the partial keyword. For example, you could turn this
namespace MyNamespace
{
class MyClass
{
void MyMethod() {}
void MyOtherMethod() {}
}
}
Into this
namespace MyNamespace
{
partial class MyClass
{
void MyMethod() {}
}
partial class MyClass
{
void MyOtherMethod() {}
}
}
Functionally they're the same and in both cases you'd call the methods like this
MyClass.MyMethod();
MyClass.MyOtherMethod();
This maybe a very simple question! But I have been scratching my head for an hour now! I have two files as below:
Assembly1.cs
Program.cs
I thought when I use internal keyword before a class name I won't be able to instantiate it in other classes, right?
https://msdn.microsoft.com/en-us/library/7c5ka91b.aspx
But why am I not getting an error message for this here? I maybe missing something very obvious here.
// Assembly1.cs
namespace InternalTest
{
internal sealed class BaseClass
{
public static int intM = 0;
}
}
// Program.cs
using System;
namespace InternalTest
{
class Program
{
static void Main(string[] args)
{
var myBase = new BaseClass();
Console.ReadKey();
}
}
}
Internal means class is accessible within the assembly.Above class is in same assembly hence no error.If you want to see the error then follow below step
1) Create Library project
2) Create Base Class in that project
3) Create Console project
4) Add reference of first project dll
5) Now try to create instance, you will see the error
Additional Info
If you want to access internal members in your console project then add below attribute in AssemblyInfo.cs of Library project
[assembly:InternalsVisibleTo("[AssemblyNameOfConsoleProject]")]
Because both classes are on the same namespace.
//InternalTest
namespace InternalTest
{
internal sealed class BaseClass
{
public static int intM = 0;
}
}
//the same here InternalTest
namespace InternalTest
{
class Program
{
static void Main(string[] args)
{
}
}
}
There must be something simple that I'm missing. I have two partial classes, in two different assemblies, and I'm not able to reference a private static method in one partial class from the other partial class.
For example, in the FirstHalf assembly, I have the following class:
namespace FirstHalf
{
public partial class TestPartialClass
{
private static void PrintFoo()
{
Console.WriteLine("Foo");
}
}
}
Then, in the SecondHalf assembly, I have the following class:
namespace FirstHalf
{
public partial class TestPartialClass
{
public static void Main(string[] args)
{
Console.WriteLine(PrintFoo());
}
}
}
However, when I try to invoke PrintFoo() from the SecondHalf assembly, I get the following error:
CS0103: The name 'PrintFoo' does not exist in the current context.
What's going on, here? I have a reference from SecondHalf to FirstHalf, so Visual Studio does know that there is a dependency between the two.
You can't split a partial class between two assemblies; they are actually being compiled as two different classes.
If you really want to accomplish something like this across assemblies, with sharing of 'private' members, you can get something similar by creating a base class and inheriting it:
namespace FirstHalf
{
public class Base
{
protected static void PrintFoo()
{
Console.WriteLine("Foo");
}
}
}
namespace SecondHalf
{
public class Derived : FirstHalf.Base
{
public static void Main(string[] args)
{
PrintFoo();
}
}
}
That said, there is probably a cleaner way to accomplish what you're trying to do using some form of composition; the details depend on your particular application.
Whenever I read questions RE this, or a similar topic of static inheritance, the replies are usually that this is not supported (we know that), and the reason is given as being because this is a poor design and there's probably a better way to do it. I'd love to find a better way of doing it so am open to all suggestions - here's what I am trying to do.
I have a class which has no instance data. All the methods are static. Let's call this class BaseStatic. I now want a new static class (well several of course but lets stick to one) which inherits from this static class and adds some new static methods, let's call this SubStatic.
What I want consumers to be able to write is:
SubStatic.MethodFromSub();
and also
SubStatic.MethodFromBase();
I know I could also write:
BaseStatic.MethodFromBase()
explicitly but then consumers have to know which class implements which methods. I can't do this with inheritance because I can't inherit one static class from another. So what's a better way of doing it?
Now, I know I can have these classes as instance classes, and I can define all the methods as static - that will give me the behaviour I described above but leads to other problems, namely:
When I do this:SubStatic.MethodFromBase() the SubStatic static constructor is not called because the method is running in the parent static class (the parent's static constructor is called)
If one of the static parent methods needs to call another method which the sub class can override, I need a virtual static method in the sub class. Which I know I can't have.
So poor design apparently - can anyone help me redo it? I know I can use instance inheritance and take proper use of virtual methods (I've had it working this way) but client code then always has to create an instance (or I suppose some singleton).
This could serve your purpose, though I certainly would include some exception handling and accompany its implementation with a great deal of documentation as to why and how it works.
When the static constructor for Base is run (once) all assemblies that are currently loaded in the app domain are catalogued, selecting the types that derive from Base. Iterating over those, we run the static constructors. It is worth noting though, that this no longer guarantees the cctor for each implementation will be run exactly once, logic would have to be added to each of them to re-make that assertion. Moreover, types that are loaded after the cctor for Base has been run would not be initialized by calls to methods in Base
To simulate virtual methods, use the new keyword to hide the base method. You can call the base method by qualifying it with the declaring class's name (like in class B in the example)
using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace ConsoleApplication6
{
public class Base
{
static Base()
{
Console.WriteLine("Base cctor");
var thisType = typeof (Base);
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes());
var derivations = loadedTypes.Where(thisType.IsAssignableFrom);
foreach(var derivation in derivations)
{
RuntimeHelpers.RunClassConstructor(derivation.TypeHandle);
}
}
public static void Foo()
{
Console.WriteLine("Bar");
}
}
public class A : Base
{
static A()
{
Console.WriteLine("A cctor");
}
}
public class B : Base
{
static B()
{
Console.WriteLine("B cctor");
}
public new static void Foo()
{
Console.WriteLine("Bar!!");
Base.Foo();
}
}
class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}
EDIT
Another option lies in the CRTP (or CRGP in the C# paradigm) or curiously recurring template (generic) parameter pattern
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication6
{
public class Base<T>
where T : Base<T>
{
static Base()
{
RuntimeHelpers.RunClassConstructor(typeof (T).TypeHandle);
}
public static void Foo()
{
Console.WriteLine("Bar");
}
}
public class Base : Base<Base>
{
}
public class A : Base<A>
{
static A()
{
Console.WriteLine("A cctor");
}
}
public class B : Base<B>
{
static B()
{
Console.WriteLine("B cctor");
}
public new static void Foo()
{
Console.WriteLine("Bar!!");
Base<B>.Foo();
}
}
class Program
{
static void Main()
{
Console.WriteLine("A:");
A.Foo();
Console.WriteLine();
Console.WriteLine("B:");
B.Foo();
Console.WriteLine();
Console.WriteLine("Base:");
Base.Foo();
Console.ReadLine();
}
}
}
In this case, when we call a static method on A we're really calling it on Base<A> which is different than Base<B> or Base so we can actually determine how the method was called and run the appropriate cctor.
You can achieve this by using Generics. For example you can use something like that:
public class MainStatic<T> where T : MainStatic<T>
{
public static void Foo()
{
}
static MainStatic()
{
RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
}
}
public class SubStatic : MainStatic<SubStatic>
{
public static void Bar()
{
}
}
public class Instance
{
public void FooBar()
{
SubStatic.Foo();
SubStatic.Bar();
}
}