|Property||Property with Access and/or Assign methods|
|Static method||"Function" or "Procedure" - C# methods can only be contained within classes.
However, if a method can function independently of any other method or field
in it's class, you can declare it "static" and it can be called without
instantiating an object based on that class. In C#, the alternative method type is referred to as an instance method, to denote that it is associated with an instance of of the class, whereas the static method is associated with the class itself.
|Constructor||Init() method - Constructors fire automatically just as does the VFP Init() method,
and are identified as constructors because the method name is the same as the class name.
You can have multiple constructors (see "Overloaded methods"), with different parameters, so you can have a
special "no parameters" constructor that sets fields to initial default values, and
another constructor that accepts parameters to store to fields.
|Overloaded Method||In VFP, you can create methods that have optional parameters. In C# no parameters are optional. If you need to call a method in different ways, you create multiple definitions for the method. Overloaded methods have to differ in type or number of parameters passed.|
|Destructors||Destroy() method - The one major "gotcha" with destructors in C# is that they're non-deterministic. That is, they don't necessarily fire when an object goes out of scope like they do in VFP. It happens during C# garbage collection. Garbage collection can be forced via the GC class (System.GC).
As with constructors, destructors are identified by the fact that they bear the same name as the class to which they belong, but unlike the constructor, the method name is preceded by a tilde (~).
However, if your class implements the IDisposable interface, you have a Dispose() method that client code can call to act as a Destroy(). The only reason you should be using a Destructor is when you're handling unmanaged resources. Otherwise, the managed heap should take care of everything else. This is probably a prime topic for its own wikis topic and discussion. -- Mike Helland
|Namespaces||Each class must reside in a namespace, whether it's an application-level namespace, or a framework namespace. Namespaces are not physical containers as PRGs or VCXs, they are logical constructions that can span source files, be nested, or be undefined altogether. If one doesn't declare any namespaces then an application will have a default namespace that is the same as the EXE.
The way that namespaces are somewhat like SET CLASSLIB TO is that they are a way of specifying which class you are refering to in the case of any ambiguities. If there are no ambiguities and you've added a using (C#) or imports (VB), then you don't have to specify the namespace at all when you use a member.
|Struct|| Think SCATTER NAME. A lightweight object class used to encapsulate data. Cannot inherit, cannot be subclassed. Can be instantiated without the new operator.
Unlike a SCATTER NAME object, or the new Empty Base class in VFP, a Struct can also have methods.
|LOCAL||There really is no keyword for declaring a variable, you just tell the compiler what type of variable you want and the name of it. Examples:
string stringvar; int intvar; string stringvar2 = "A real string!"; long longvar = 10; StringBuilder sb1; // StringBuilder is the name of a .NET class
However, the concept of local scope is alive and well in .NET languages. There is no concept corresponding to a "private" variable scope. All value tokens declared within a method are not visible outside of that method. However, reference tokens - tokens that hold a reference to an object instance, are visible outside of that method. Note too that in .NET reference tokens include arrays and collectcions as well as instantiated classes. I believe that there is what we would think of as a global scope for fields (what we think of as properties) if they're defined with the "Static" keyword. I don't know what the scope of reference variables are since they persist even when the method that creates them terminates - possibly the class or the namespace. Anyone that can do a better job with this please have at it!
|new||Think in VFP´s Create Object().
sb1 = new StringBuilder();
You can even use the new function when declaring variables:
StringBuilder sb2 = new StringBuilder(); DataSet MyDS = new DataSet();
In the last line, the VFP code would look something like below (for a RecordSet):
Local loRS as ADODB.Recordset loRS = CreateObject("ADODB.Recordset")
VFP: y = 0 z = iif(y=0, "Zero", "non-zero")
C#: int y = 0; string z = (y==0) ? "Zero" : "Non-zero";
y = .null. z = nvl(y, 20)
C#: int? y = null; // The ? indicates the variable is Nullable int z = y ?? 20;