Right -- it's an issue of virtual vs. non-virtual, not static vs. non-static.
For example, [this comment](https://news.ycombinator.com/item?id=31379783 ) provided code showing the issue in this branch of the thread using `static` in Java. Here's the same thing in C# without using `static` (except for `Program.Main()`):
public class Program
{
public static void Main()
{
A a = new B();
if (a is B b)
{
a.Print(); // Prints "A".
b.Print(); // Prints "B".
}
}
}
public class A { public void Print() { System.Console.WriteLine("A"); } }
public class B:A { public new void Print() { System.Console.WriteLine("B"); } }
`static` can work too because it implies non-virtual, but it's not necessary.
Generally speaking, virtual-methods resolve with dependence on the object they're called on since they consult a [virtual-method table](https://en.wikipedia.org/wiki/Virtual_method_table ). Non-virtual methods can resolve without considering the object they're called on (whether static or not) because they call the method that belongs to the apparent-type.
In C#, basically all methods are `static` by-default. Just, if a programmer doesn't explicitly mark a method as `static`, then the compiler implicitly inserts an extra argument into the call-signature for `this`.
For example:
public class A
{
// If a programmer writes this:
public void DoSomething(int x) { /* ... */ }
// ...then C# sees this:
public static void DoSomething(A this, int x)
{
if (this == null) { throw new NullArgumentException(); }
/* ... */
}
}
So if a programmer then writes `a.DoSomething(7);`, C# basically automatically converts that into `A.DoSomething(a, 7);` for them. It's basically syntactic-sugar.
Then there's a difference between C# and Java: in C#, non-static methods can be `virtual` if marked as such, whereas in Java, all non-static methods are automatically `virtual`.
> If you’re writing code calling static methods on instances of classes, you deserve to have that code broken.
, was that that's basically what C# does by-default, ignoring syntactic-sugar.
Because, in C#, methods aren't `virtual` by-default, so when C#-programmers call a default method on an instance, they're calling it non-virtually, much like a Java-`static` method -- it may look a little different in C# due to the syntactic-sugar, but it's basically the same thing.
Of course, I don't mean that they look exactly the same, due to the syntactic-sugar. Just that they're conceptually the same in terms of logical-structuring and behaviorally the same in terms of what they actually do (e.g., how they printed the same responses in those examples).
For example, [this comment](https://news.ycombinator.com/item?id=31379783 ) provided code showing the issue in this branch of the thread using `static` in Java. Here's the same thing in C# without using `static` (except for `Program.Main()`):
`static` can work too because it implies non-virtual, but it's not necessary.Generally speaking, virtual-methods resolve with dependence on the object they're called on since they consult a [virtual-method table](https://en.wikipedia.org/wiki/Virtual_method_table ). Non-virtual methods can resolve without considering the object they're called on (whether static or not) because they call the method that belongs to the apparent-type.