Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's actually the default in C#.

This is, in C#, all methods are called according to an object's apparent-type, not its actual-type, by default. To get the Java-behavior, a C#-method would need to be declared `virtual` (or `abstract`), and then more-derived methods would need to choose to `override` them (rather than hide them, often via `new`).

Part of the advantage might be performance. This is, methods that go with the apparent-type don't need to do a virtual-lookup-table resolution, which can save some work in method-calls.

Another advantage is that it can help provide more flexibility in class-hierarchies, since more-derived classes can "hide" less-derived classes' methods without overriding them. It's probably not something that folks really need to do too often, but it's nice to have an easy solution when such a case occurs.



You're talking about virtual vs non-virtual. static is a whole separate thing. static calls are always resolved at build time. You don't even need an instance at all. And probably shouldn't use one.


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.


> it's an issue of virtual vs. non-virtual, not static vs. non-static.

That's what you started talking about, but that's not what I'm talking about.

> "calling static methods on instances of classes"

That's from an ancestor, somewhere upthread. Here it is as a c# expression.

    "abc".Format("size: {0}", 7)
Sensibly, c# doesn't allow this, but some languages do. I don't recall which, but I've definitely seen this.

Maybe I'm not understanding a word or something, but the description of the problem is definitely about "static".


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.

C# even lets programmers write methods that can be called on an instance OR as `static`: [extension methods](https://docs.microsoft.com/en-us/dotnet/csharp/programming-g... ).

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`.

---

Anyway, my point about the perspective from [this comment](https://news.ycombinator.com/item?id=31383483 ),

> 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.

To demonstrate that same-ness, I took the Java code that used `static` from [this comment](https://news.ycombinator.com/item?id=31379783 ), then showed the same without `static` in C# in [this comment](https://news.ycombinator.com/item?id=31385859 ).

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).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: