Something odd, to my mind, is being suggested in there - In the Main() member function of the OneMethod class, a new instance of OneMethod class is being instantiated…
using System;
class **OneMethod**
{
public static void Main()
{
string myChoice;
**OneMethod om = new OneMethod();**
...
I understand why this is being done - to be able to call the getChoice() method (for the sake of the tutorial) but it seems unusual and confusing to create an instance of a class inside a method belonging to that class.
Is this normal? Is it bad practice? Is it unique to the way C# works?
It is absolutely correct, normal, and common in object oriented languages.
In fact, I’d consider it very good practice for the Main method of an application to do nothing but parse the command line arguments, and then immediately call a constructor of the application class. That way the application can be easily used both standalone and as a component of a larger application.
Another time when it is common to see this is when working with immutable classes. Consider an immutable Integer class:
class TestInteger {
private int val;
public TestInteger(int val) { this.val = val; }
public plusOne() { return new TestInteger(this.val + 1); }
}
The plusOne method, because it can’t modify the value of the current instance, creates a new instance with the value incremented, so calls TestInteger’s constructor to create a new instance with the value incremented.
My experience of OOP is basic and outdated, and is with C++ (many years ago) where the main() function would be a non-OOP function and would use classes defined totally separate from the main() function. And to a lesser extent - PHP, where classes are used in the global scope (or in the scopes of different classes)
It just threw me a bit, and I had to ask if what the tutorial writers were doing was good practice.
The key is that the main method is static. Using a static method inside a class to instantiate an instance of that class is common and considered kosher.
Instantiating a class instance inside a method of the class itself is an acceptable practice. You could even instantiate a new instance in a non-static method, such as doing a myTreeNode.AddNewNode(Object newData) that takes newData and stuffs it inside a new TreeNode(newData) and attaches it on to myTreeNode. What you have to be aware of is whether or not doing so makes sense according to your business/data model and making sure you avoid an infinite recursive situation.
The following code is right out.
class TestInteger {
private int val;
private TestInteger internalTI;
public TestInteger(int val)
{
internalTI = new TestInteger(val);
}
public plusOne() { return new TestInteger(this.val + 1); }
}
That’s because it’s infinitely recursive, though. There’s be nothing wrong with doing that with a suitable base case. Say a constructor that created a Peano number from a positive integer:
class Peano {
private Peano parent
public Peano(int i) {
if (i <= 0) {
parent = null;
} else {
parent = Peano(i-1);
}
}
}
I mean, it would still be weird, but calling the constructor from the constructor isn’t totally out there if you have a plan*.
Unless C# in particular has some sort of built-in guard preventing this, I haven’t used the language extensively.
The particular pattern of a static main() function instantiating the class of which it is a member is a symptom of C# being one of those languages that seems to be allergic to free functions. You see the same thing in Java. That said, it’s a perfectly idiomatic pattern in both languages.
And of course, it’s also perfectly reasonable for an instance of a class to create further instances of its class in the process of executing its own methods – often that’s the only reasonable way to implement some behaviors.
Nope, not even limited to C#. Methods (usually static) that produce instances of a class or subclass are called “factory” methods these days; they’re extremely common in modern application frameworks: Cocoa/Cocoa Touch and WinRT/.NET both make extensive use of them. The particular form you’ve got here (where the app just uses the object, rather than returning it) in a “Main” method is fairly specific to C# and Java, though.
I understand now, but I notice something that raises another question…
[s]I have created a Windows Forms application within Visual Studio. (Way before I started following the tutorial) I added my own member methods to the Form1 class.
None of the methods are static, but they all work fine when called from elsewhere in the class. They are called directly, not using an instantiated object of type ‘Form1’
I don’t quite understand this. Based on what we’ve discussed so far wouldn’t there need to be an instantiation somewhere somewhere (myForm1 = new Form1()) and then my non-static methods called like this myForm1.myMethod()?[/s]
Edit, I think I actually do understand this. I recall this being entirely possible in C++ OOP. I can’t quite explain it but I think the original example only needed to be instantiated because it was being called from a static method.
If a method is not static, it is an instance method and requires an instance of the class to run. When you call an instance method from another instance method, the instance you are using is, if not otherwise specified, the same as the one the method you are calling from is using. I.e. test1() is a synonym for this.test1().
test2() is incorrect because a static method does not require an instance to be run, so there is no “current instance” to use for the call to test1(). Since test1() is an instance method, it needs a current instance, so it can’t be called, except by manually creating/acquiring an instance to call it with, as test3() does.