Quote: Original post by JWalsh
Shawn,
Thanks for the honest post. If people dont express confusion or a lack of understanding, then everyone just assumes other people are understanding the material, and are afraid to ask. Myself, Sam, Washu, and the other people who are volunteering their time to help people with C# are happy to answer any C# questions, regardless of how "newbish" the questions may seem. We all have to start somewhere, right? If you are feeling confused about something, please ask questions. That's the only way to learn.
At any rate, let me take some time to cover a few key terms and definitions to help people get started.
Computer Program: A computer program is just a series of instructions that the computer follows in a pre-defined sequence, in order to accomplish something intended by the program author. In other words, a program is just us telling the computer what to do.
Programming Languages (A history): Initially computer programs were developed directly in machine language. This was represented as 1's and 0's in punch-cards and magnetic tape. After a while, programmers realized that rather than having to tell the machine how to do things in its language, they could actually tell the computer what to do in a language closer to their own. But in order to do this, they needed an interpreter of sorts. So they wrote a program (in 1's and 0's) which took instructions in something a little easier to remember, and converted it into machine language. This was how assembly language was born.
Unfortunately, assembly language is still very difficult to work with, as every little minute operation is its own instruction. Also, assembly language tended to be highly dependent upon the underlying architecture of the hardware. In other words, you pretty much had to know how a processor worked internally in order to program it. Once again the brilliant minds of their time got together and realized that could create an even higher level language, which looked as close to their native language as possible, which could then be compiled into assembly language instructions for the indicated hardware, and finally assembled into machine code. This was how High Level programming languages were born.
The most common "high level" languages of yesterday were C, COBOL, Pascal, Fortran, and Basic. And while each of these languages still experiences some popularity in different circles, they had one dramatic drawback. They were procedural. Although they, C in particular, enjoyed quite a bit of popularity, programmers found it difficult to program even in these high level languages because the data they were working with wasn't necessarily connected in an intelligent way to the operations they were performing on that data. They might have a set of student records, but any changes to those records must be made by external functions which took the records as input, modified them, and then allowed the caller to obtain the modified records. This was a hassle. Also, because data was frequently global, and passed around like a bad STD, debugging applications was incredibly difficult, and maintenance was expensive and time consuming. This was how Object Oriented Programming languages were born.
Only about 10 years after C became popular C++ was invented. This was a breath of fresh air as for the first time ever (commonly so, anyways), programmers could group their data together with their functions in an intuitive way. They called these groupings "classes". There was encapsulation which allowed programmers to hide the implementation details from others using their objects, and there was inheritance, which allowed others to assume code they had already written and extend it with their own. All was glorious...except, programs and libraries written in C++ dont play well with programs written in Visual Basic or any other compiled language. This is where Component Oriented Programming was born.
Microsoft realized that the ultimate solution was the creation of shareable components, which could be written in any language that abide by a set of common rules. So they set out to create a number of different technologies which might allow this, finally ending up with Microsoft .NET. And here we are today.
.NET: This is a technology made up of two components - The Common Language Runtime and the .NET Framework Library. The point of .NET is the creation of shareable components, in any .NET compatible language, which can be used to build sophisticated desktop, web-based, and enterprise applications. It is really just the next evolution in the age-old goal of software engineering, which is to develop software without having to constantly re-invent the wheel.
Common Language Runtime (CLR): The Common Language Runtime is the heart of .NET. It is a sort of virtual machine that Just-In-Time compiles Microsoft Intermediate Language (MSIL) into machine-specific code. It also handles garbage collection and system security to make sure unsafe code cannot be executed.
Microsoft Intermediate Language (MSIL or IL): MSIL is code which is partially compiled. It's not compiled all the way down to machine language, but it has been checked for proper semantics, syntax, and has been brought down into a common set of instructions which is independent of any particular programming language. Any .NET compatible language must adhere to the Common Language Specification, which is a detailed document that describes what the output must be, and what functionality must be exposed, by any programming language and compiler which attempts to be .NET compliant. Once this has been accomplished, compiling the language turns it into IL, which is then run by the CLR.
Assembly: Any Intermediate Language file is an assembly. Assemblies typically come in two forms - applications and libraries.
C# Application: A C# application is any application who's instructions were initially written in C#. Incidentally, once the application is compiled, it is turned into Intermediate Language anyways, and it is technically possible to write programs directly in Intermediate Language - though this would be time consuming.
C# Library: A C# library is any library file who's instructions were initially written in C#. As with applications, once the code-base has been compiled it is turned into IL.
Namespaces: Whenever a programmer writes instructions for a computer, they do so using variables which they create. These variables have names, called identifiers, and they have types (see below). To make sure the names of variables, as well as their types do not collide with other peoples identifiers and types, they are grouped into namespaces. Think of it this way...lets say my name is Adam. At my university there may have been hundreds of Adams. How would someone know who I am by name from someone else with the same name? Simple, by also using my last name. If you were to say "Adam Smith", then people would immediately know you didn't mean "Adam Johnson". In other words, the last name of the individual helps to qualify WHICH individual is being referred to. Namespaces are the exact same thing. By grouping types and identifiers into namespaces, we are in essence giving them a last name. And whenever there is confusion about which type to use with a similar name, a programming can fully qualify it by identifying the namespace.
Ex.
JWalsh.Collections.Vector is different from JWalsh.Math.Vector. Even though both types are called "vector", by grouping them into namespaces the compiler can identify which vector I'm referring to.
Types: Every variable in C# has a type. A type identifies how much memory a variable needs, and how the data in that memory should be interpreted. For example, in C# if I specify something as type "int", I'm identifying it as an Integer and needing 4 bytes of memory. Because C# is a "Strongly Typed" language, once a variable has been declared a specific type, only other data of the same type can be stored at that address in memory.
Reference Types vs. Value Types: Some types such as integers, floating point values, and structures are value types. This means they are allocated on the stack (the fastest allocatable memory location), are quickly created, and quickly destroyed. They are meant for "local" variables which will be used only for a short period of time. Whenever you pass a value type into function, or assign it to another variable, a copy of the data is made. This is usually not a problem as, in general (except for structs), the size of value types are very small.
In contrast, reference types are usually larger and more complex. They are allocated on the heap, which is a bit slower, and intended for long-term use. Whenever you pass a reference variable around, rather than copying the data at the address in memory, it instead just copies the address.
Lets come up with a wacky example. Lets assume for a moment that a pet is a value type, and a human is a reference type. If I were to give my pet to someone, I would actually give them a clone of my pet. Now we both have an identical looking pet. But we know better to become too attached to our pets dont we...yessss...so when we're done using our pets, we just toss them out, and re-use their food bowls for our next pet. =)
Humans on the other hand cannot be cloned. (it's illegal...seriously). So instead of cloning people, we just go hang out with our other friends while leaving our phone number or address with our other friends. So we're only physically located at one place at a time, but everyone who knows us can still contact us. (yeah, that was all a crappy, convoluted example. Sorry)
Statements: Statements are any instruction you give to the computer. These can be memory allocation, branching, looping, or even mathematical expressions. For easier understanding, any line which ends in a ';' or has a set of '{ }' is probably a statement.
Expressions: An expression is just a statement which results in a value. ex. int myInteger = 2 + 3; that is an expression who's value is 5, and is assigned to MyInteger.
Structs: Structs are user-defined value types. They are useful for things which are less capable of being represented by a single value. For example, if I asked you how much money you had in your pocket, you COULD just tell me the numerical value. ie $1.38. But if I asked you which coins you had in your pocket, you'd now be unable to express it as a single value. Instead, you'd need to provide me with a set of related values. The above example might be 5 quarters, 1 dime, and 3 pennies. If I wanted to represent that as a structure I could say:float Money = 1.38;struct Coins{ int CountOfQuarters; int CountOfDimes; int CountOfNickels; int CountOfPennies;}Coins myCoins = new Coins();myCoins.CountOfQuarters = 5;myCoins.CountOfDimes = 1;myCoins.CountOfPennies = 3;
Classes & Objects: Classes are similar to structs, in that they serve a similar purpose. They are designed to group data together. However, classes are much more sophisticated. In specific, they are reference types rather than value types and support class inheritance with polymorphism. Whenever you create an instance of a class, it is called an object.
Members: All items within a struct or class are its members. These include variables, functions, properties, and events.
Methods: This is a fancy name for a class's functions.
Fields: This is a fancy name for a class's variables.
Properties: These are C#'s setters/getters. They are a new construct which looks like a Field, but behaves like a Method.
Events: These are members of a class which make notifications possible. How/why these are used will become more obvious later.
Operators: These the symbols seen in C# source such as +, -, /, (), etc...and perform operations upon their operands.
Base Classes, Inheritance and Derived Classes: Sometimes you, or someone else, has written code which you'd like to take advantage of, but don't want to have to go through the trouble of duplicating. In this case, you can derive a new class from an existing class. The class which already existed is the "Base Class", while the new one you're creating is the "Derived Class". The process of basing a new class upon an existing class is called "Inheritance", and simply means that all public and protected members (except for the constructor) of the base class are now part of the derived class.
All of the above, except for my history lesson, is contained and presented in a far more elegant fashion within the text. If you're having trouble with a specific subject, feel free to ask questions, or request aid on identifying where in the text a subject is covered in the most enlightening fashion.
Hope this helped!
Wow I always thought of "members" as data members of a class.... and "methods" were functions of a class... It seems redundant to group Methods and Fields into a bigger classification of Members... Maybe its just because I've thought that for so long.
-durfy