When to use C# keywords
September 24, 2008 7:30 AM   Subscribe

Help me understand keywords in C# functions.

I am trying to quickly learn asp.net/c# and have a php background. I am trying to understand the basic approach to C# keywords like public, protected, private, instance, static, declared, inherited, etc. When I write a basic function how do I decide which ones to use if any? I do know you use void when you don't need a value returned. Functions seemed a lot easier in php.
posted by zobot to Technology (9 answers total) 1 user marked this as a favorite
 
These are pretty fundamental to the language- and to OO principles. You would be best off getting a book. The Wrox C# introduction is good- not too long and quite well written.

PHP supports many of the same, so you can play with the same principles in a more familiar environment.
posted by mattoxic at 7:56 AM on September 24, 2008


public, protected, private, friend: access specifiers; what functions can call this one
instance: belonging to a particular instance of a class object
(class) static: belonging to the class, and thus shared by all instances (and all everything, if it's also public)
inherited: belonging to a superclass

When in doubt, make instance variables private, with public accessor functions; this allows you to chnage the implementation without changing your public interface.

Better, write the minimal set of public functions that allow the object to manage its own, private, state.

Even better: compose your objects out of well-known, thoroughly tested library objects, with as much "glue" as appropriate.

Even better: read something like Eckel's Thinking in C++.
posted by orthogonality at 7:58 AM on September 24, 2008


Functions seemed a lot easier in php.

If you have been writing procedural code in PHP, switching up to C# will be a bit like upgrading from a skateboard to flying the space shuttle. You need some background in Object Oriented Programming, ideally some design patterns, and then C#.

A quick guide like this might help you get up to speed, but it is very easy to write terrible unmaintainable code in an object oriented language like C# or Java if you don't have a thorough grounding in OOP and patterns.
posted by b1tr0t at 8:00 AM on September 24, 2008


If you have been writing procedural code in PHP, switching up to C# will be a bit like upgrading from a skateboard to flying the space shuttle.

Heh, a very appropriate analogy. The stuff you're asking about are language fundamentals than can't be quickly understood. Check the archives for question about learning object-oriented programming.

I'm not sure what the best OO intro book is these days, but once you've got a foundation in OO, read Code Complete. There isn't a better single book about software engineering out there anywhere, IMHO.
posted by Nelsormensch at 8:53 AM on September 24, 2008


You should use the most restrictive qualifiers that don't break functionality.

For the access specifiers:
private unless the method needs to be callable outside its immediate class.
protected unless the method needs to be callable outside the inheritance tree from its immediate class.
public as the last resort.

C# has accessors, which are great in that they let you keep nearly every data member (vs. method member) private. At least until you are experienced enough to know what all the considerations are for not doing so, make all your data members private and use protected or public accessors as necessary. See: MSDN: Accessors

For static/instance, use static whenever the method does not need to access instance data.

Inheritance related stuff:
virtual: this is only for methods that are going to be different in classes that inherit from a base class. The classic example of a virtual method is the shape.draw() where square.draw() inherits some shape traits and functionality but defines its own method of draw()ing, and triangle does likewise, and so on. Unless you're producing a library for others to build on and you have to anticipate what they might like to override the easiest thing is to not declare anything virtual until you actually need to override it in a subclass.

override: just indicates the method takes precedence over an inherited virtual method of the same name. The compiler will for the most part notify you if you either use or fail to use this one incorrectly, so no worries. Turn on warnings.

new: this is a rarely-used counterpart to override that hides a base method rather than overriding it, which makes a difference in certain cases where a derived class is casted to its base. In the override mode the base method is still under there and will be called, in new mode it's been completely supplanted. In general, don't use 'new' methods.
posted by moift at 9:10 AM on September 24, 2008


I present: The C# Keyword Reference. The first 80% of programming is knowing how to use the documentation to find what you want. The second 80% is experience.

A brief example (style is for brevity--you should indent and stuff correctly):
class Foo {
  public void bar() {...} 
  private void qux() {...}
  public static void splat() {...}
}
Any other object can call Foo::bar(), but only Foo can call Foo::qux(). E.g.:
Foo myFoo = new Foo();
myFoo.bar(); // legal
myFoo.qux(); // compile error
However this is legal:
public void bar() { qux(); }
The last interesting one is static. Static means "there is only one for everyone." Which means if you have 20 instances of Foo, they all call the same splat() function. This is interesting because its basically like a regular old non-classy function, but in the functions scope. So you don't even need to instantiate an object to call it:
Foo::splat();  // legal anywhere (since it's public static.)
The downside is static members can only refer to other static members, since they don't know which instance of the class to use for non-static member access. You probably won't be implementing static functions right away, but you'll be calling them as part of the framework.
posted by jeffamaphone at 9:20 AM on September 24, 2008


Feel free to mefi mail me if you have specific questions as your quest continues.
posted by jeffamaphone at 9:22 AM on September 24, 2008


This is not a C# question, its an OOP question. I'm a hobbyist programmer who, like you, started by learning a procedural language. The real downside with learning stuff like basic, php, etc is that you get the mindset of working from top to bottom. In OOP you need to break everything down into fuctions and break up your procedure inside main() and within the functions.

You can read one of the many OOP books and tuturials out there, but I recommend theHow to Think Like a Computer Scientist free e-book. It'll help you break free of procedural thinking and is written for a novice. Many books and tutorials you'll find assume at least a basic level of programming (non procedural) literacy.

If you want to write proper modern applications then you're really going to have to learn some OOP. At first it seems like a hassle but once you start re-using functions and work with objects you'll find that it makes everything a whole lot easier. It also helps make the code readable to someone other than you.
posted by damn dirty ape at 9:50 AM on September 24, 2008


Note: I'm an Actionscript programmer, but most of the same concepts apply.

So in Object Oriented programming, you have containers called classes. By "container," I mean a structure that contains a certain chunk of code and separates it from other code, much as a chapter separates a chunk of a novel from other chapters.

So...

Class Packman
{
// code that makes the pacman work
}

Class ghost
{
// code that makes the ghosts work
}

Inside classes, you stick variables and functions. When variables and functions are inside classes, we usually call them properties (variables) and methods (functions).

Class Packman
{
var lives;

function move() { ... };
}

Now, if I want to actually make a packman, I'd do this in the main body of my program:

var p:Packman = new Packman();

the variable p now is an instance of the class Packman, and I can do things like this:

print(p.lives);
p.move();

If I want to have two packmans, I can do this:

var p1:Packman = new Packman();
var p2:Packman = new Packman();
p1.move();
p2.move();

Now, let's say that I'm going to share my Packman class with other programmers. I say, "Hey guys, if you're making a packman-like game, I have some of the work done for you. I've created a working, self-contained Packman class. Just download it, type var p:Packman = new Packman(), and you're good to go."

One of those programmers might do something like this:

var p:Packman = new Packman();
p.lives = -8;

That second line might screw things up. When I created the class, it never occurred to me that some person (or process) might set lives to a negative number. Really, no one needs to access lives at all. It's just an internal counter that the class needs to determine whether or not the packman is still alive. So I alter my class as follows:

Class Packman
{
protected var lives;

function move() { ... };
}

Because lives is protected, it can only be used by functions that are INSIDE THE CLASS.

Class Packman
{
protected var lives;

function move() { ... };

function amIAlive()
{
if (lives <> }
}

Now, if a developer writes...

var p:Packman = new Packman();
p.lives = -8;

... he'll get some kind of errors, e.g. "lives is a protected property. It can't be accessed outside its class."

To make things clearer (and more accurate), I'm going to amend my class as follows:

Class Packman
{
protected var lives;

public function move() { ... };

public function amIAlive()
{
if (lives <> }
}

Think of a car. The steering wheel and the gas pedal are like public methods; the engine, because it's under the hood, is protected.

When I first started OOP programming, I understood this in theory, but I didn't get why it's important. As a hobbyist, I wasn't programming for other developers. I was just programming for myself. So why not just make everything public? That way, I could access it if I wanted to. And I was sure I'd remember not to do dumb things like set lives to a negative number.

I learned the error of my ways when I worked on my first really large application. Even though I was the only developer, the app was too big for me to hold in my brain all at once. So I had to write one part, test it, make sure it worked, and then forget about it. I couldn't hold all sorts of rules in my head, such as "remember not to set var x to a negative number" (or remember to ensure that no other process sets it to a negative number). So I needed structures in place to protect me from myself. Making certain variables and functions protected did just that. It stopped me from making fatal mistakes.

Moving on:

Classes can be based on other classes:

Class MsPackman extends Packman
{

}

By doing this, MsPackman automatically inherits lives, move() and AmIAlive(). Or does it? I made lives protected, and if MsPackman can access it, doesn't that violate the rules? MsPackman is not Packman. How can she can access Packman's protected vars and functions?

Actually, protected allows that (at least in Actionscript -- check the specifics of C#). Protected vars and functions can be accessed by their own class and any subclasses. Private vars and functions can only be accessed by their original class. So...

class A
{
public var x;
protected var y;
private var z;
}

var a:A = new A();
print(a.x); //ok. x is public
print(a.y); //error
print(a.z); //error

class B extends A
{
public function reveal()
{
print(x); //ok, inherited
print(y); //ok, inherited
prind(z); //error
}
}

Classes themselves can be grouped in packages:

package gameboard
{
public class maze { ... }
public class highscores { ... }
}

package gamepieces
{
public class Packman { ... }
public class Ghost { ... }
protected class DrawingUtilities { ... }
}

I've protected DrawingUtilties, because they are only needed by Packman and Ghost (they are only needed within the package. So now this is legal:

public class Packman
{
protected function drawMe()
{
var d:DrawingUtilities = new DrawingUtilities();
d.drawCircle();
}
}

but you can't do this...

public class maze
{
protected function drawMe()
{
var d:DrawingUtilities = new DrawingUtilities(); //error
d.drawCircle(); //error
}
}

DrawingUtilities is protected, which means it can only be used within its package.
posted by grumblebee at 11:41 AM on September 24, 2008


« Older Help us with a name for our business   |   Mac server backup software Newer »
This thread is closed to new comments.