Programming/C Sharp: Difference between revisions

From Dev Wiki
Jump to navigation Jump to search
m (Minor formatting)
(Add some notes)
 
(8 intermediate revisions by the same user not shown)
Line 2: Line 2:


It's used often in large, enterprise/business scale projects, due to having solid scaffolding for enforcing consistency through the project, which allows many people to work on a given project with less maintenance overhead. This is accomplished via things like required strong typing and good support for the [[interface class]] structure.
It's used often in large, enterprise/business scale projects, due to having solid scaffolding for enforcing consistency through the project, which allows many people to work on a given project with less maintenance overhead. This is accomplished via things like required strong typing and good support for the [[interface class]] structure.
== Other ==
* Classes are always passes by reference.
* Structs and value types (when not part of a class) are always passed by value.




Line 87: Line 92:
         break;
         break;
  }
  }
== Functions ==
Functions in C# are syntactically handled similarly to C, with a few modifications. The format is:
<accessibility> <return_type> <function_name>(<args>)
{
    // Function logic here.
}
For example:
public void MyFunc(int my_int, string my_string)
{
    // Function logic here.
}
=== Accessibility ===
Accessibility levels indicate what can and cannot access the given variable or function. The most types are as follows:
{{ note | See [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels this link] to see the all levels in the Microsoft docs. }}
* <code>public</code> - Anything can access it.
* <code>protected</code> - This class and all inheriting children can access it.
* <code>private</code> - Only this class can access it. Not even inheriting children have access.
=== Return Type ===
The return type is exactly that. Aka, the type of the variable that the function returns on function exit. If a variable does not return anything, then the type of <code>void</code> type.
== Basic Data structures ==
=== Arrays ===
Arrays are one of the most common data structures. See [[Arrays]] for more info.
In C#, all indexes for a given array must hold the same data type.
==== Declaring Arrays ====
Declare an array by specifying the type, followed by brackets, followed by the array name.
string[] my_array;
Then we can initialize the array by declaring the number of indexes. For example, to declare 4 indexes, use:
my_array = new string[4];
If you want to initialize with pre-populated values, you can take it a step further with something like:
my_array = new string[4] { "Index 0", "Index 1", "Some String Value", "Final Index" };
Finally, note that you can combine declaration and initialization into one line.
==== Accessing Array Values ====
The syntax to access an array is as follows:
// Update index 1.
my_array[1] = "Test Index 1";
// Read index 1.
Console.WriteLine(my_array[1]);
To access all array indexes in order, use a standard for loop.
for (int index = 0; index < my_array.Length; index++)
{
    Console.WriteLine(my_array[index]);
}
=== Dictionaries ===
Dictionaries can be incredibly powerful. See [[Dictionaries]] for more info.
==== Declaring Dictionaries ====
Similarly to C# arrays, once the data type is declared in a dictionary, it cannot be changed. However, note that "keys" and "values" in a dictionary can each hold a different, unique data type.
For example, to declare a dictionary of string keys and int values, use:
Dictionary<string, int> my_dict = new Dictionary<string, int>();
==== Accessing Dictionary Values ====
To set new key-value pairs, use:
my_dict.Add(<key>, <value>);
To read an existing key-value pair, use:
my_dict[<key>]
To update an existing key-value pair, use:
my_dict[<key>] = <updated_value>;
To remove an existing key-value pair, use:
  my_dict.Remove(<key>);
==== Example ====
Here's an example of a dictionary for a hypothetical business trying to track count of items sold.
// Create our dict.
Dictionary<string, int> product_sold = new Dictionary<string, int>();
&nbsp;
// Add initial values.
product_sold.Add("Ice Cream", 50);
product_sold.Add("Burgers", 56);
product_sold.Add("Pizza", 102);
&nbsp;
// Sold another pizza. Update value.
product_sold["Pizza"] += 1;
=== Structs ===
Structs are essentially a means to group sets of variables together. They are handled very similarly to C structs.
Unlike C# arrays or dicts, structs are able to combine as many variable types as desired.
==== Struct Declaration ====
First, declare the struct type itself.<br>
If familiar with classes, this will look a lot like declaring a simplified class that has only class variables and nothing else.
struct MyStructObject
{
    public bool test_bool;
    public int test_int;
    public string test_string;
}
Once the struct type is declared, we can create instances of it to use.
MyStructObject a_struct = new MyStructObject();
==== Accessing Struct Items ====
Structs are basically containers for holding the associated variables within. Thus, we can easily access the contained variables with syntax that should look fairly familiar.
// Set or update struct values.
a_struct.test_bool = true;
a_struct.test_int = 5;
a_struct.test_string = "My test string";
&nbsp;
// Print struct values.
Console.WriteLine(a_struct.test_bool);
Console.WriteLine(a_struct.test_int);
Console.WriteLine(a_struct.test_string);




== Classes ==
== Classes ==
A class can be thought of as a struct that can have functions built into it.
Classes are generally defined in new, separate files. A good rule of thumb is to only include multiple classes in one file if they are nested, inner subclasses within the first class.
Classes are generally defined in new, separate files. A good rule of thumb is to only include multiple classes in one file if they are nested, inner subclasses within the first class.


Note that in C#, class variables and methods are often called with <code>this.<value></code>, to help differentiate between local and class level values. However, this is optional and will not always be followed.
{{ note | In C#, class variables and methods are often called with <code>this.<value></code>, to help differentiate between local and class level values. However, this is optional and will not always be followed. }}


=== Class Variables ===
=== Class Variables ===
Line 187: Line 317:
             // Check if our provided value is valid before setting.
             // Check if our provided value is valid before setting.
             // In this case, we simply make sure it's 3 characters or greater.
             // In this case, we simply make sure it's 3 characters or greater.
             if (this.test_string.length > 2)
             if (this.test_string.Length > 2)
             {
             {
                 this.test_string = value;
                 this.test_string = value;

Latest revision as of 19:54, 22 April 2023

C# is a higher level version of C. It was designed by Microsoft, and for the longest time, was generally only supported on Windows.

It's used often in large, enterprise/business scale projects, due to having solid scaffolding for enforcing consistency through the project, which allows many people to work on a given project with less maintenance overhead. This is accomplished via things like required strong typing and good support for the interface class structure.

Other

  • Classes are always passes by reference.
  • Structs and value types (when not part of a class) are always passed by value.


Comments

Inline Comments

// This is an inline comment.

Block Comments

Because there is minimal difference in C# between inline and block comments, these are really only useful when declared above a class or function declaration line.

This is because C# knows to treat this as documentation and adds special logic around it. For example, hovering over a class instantiation will display the block comment data for that class.

/// This is a block comment.
/// Comment line 2.
/// Another block comment line.

Block/Region Declaration

Regions are used for organizational purposes, and allow for code folding at the click of a button. To be useful, both the start and end must be declared.

#region MyRegionName
 
...
 
#endregion MyRegionName


Variables

Variables are strongly typed in C#. That means that you must declare the type (bool, int, string, etc) as well as the variable name.

Variable Definition

bool a_bool = true;
bool b_bool = false;
string my_var_1 = "This is ";
string my_var_2 = "a string.";

Variable Usage

Console.WriteLine("Printing variable values.");
Console.WriteLine(a_bool);
Console.WriteLine(b_bool);
Console.WriteLine(my_var_1 + my_var_2);

Variable Casting

Variables will be treated as the originally indicated type until a cast statement is used.

For example, to convert a boolean to an int, use:

bool a_bool = true;
int converted_bool = Convert.ToInt32(a_bool);


If Statements

Basic If

if (x == y)
{
    // Logic if true.
}

Full If

if (x == y)
{
    // Logic if true.
} else if ( x && (y || z) )
{
    // Logic for "else if" true.
} else
{
    // Logic for false.
}

Switch/Case Statements

switch (my_var)
{
    case "1":
        // Logic for case value of "1".
        break;
    case "a":
        // Logic for case value of "a".
        break;
    case "test":
        // Logic for case value of "test".
        break;
    default:
        // Logic for no match.
        break;
}

Functions

Functions in C# are syntactically handled similarly to C, with a few modifications. The format is:

<accessibility> <return_type> <function_name>(<args>)
{
    // Function logic here.
}

For example:

public void MyFunc(int my_int, string my_string)
{
    // Function logic here.
}

Accessibility

Accessibility levels indicate what can and cannot access the given variable or function. The most types are as follows:

Note: See this link to see the all levels in the Microsoft docs.
  • public - Anything can access it.
  • protected - This class and all inheriting children can access it.
  • private - Only this class can access it. Not even inheriting children have access.

Return Type

The return type is exactly that. Aka, the type of the variable that the function returns on function exit. If a variable does not return anything, then the type of void type.


Basic Data structures

Arrays

Arrays are one of the most common data structures. See Arrays for more info.

In C#, all indexes for a given array must hold the same data type.

Declaring Arrays

Declare an array by specifying the type, followed by brackets, followed by the array name.

string[] my_array;

Then we can initialize the array by declaring the number of indexes. For example, to declare 4 indexes, use:

my_array = new string[4];

If you want to initialize with pre-populated values, you can take it a step further with something like:

my_array = new string[4] { "Index 0", "Index 1", "Some String Value", "Final Index" };

Finally, note that you can combine declaration and initialization into one line.

Accessing Array Values

The syntax to access an array is as follows:

// Update index 1.
my_array[1] = "Test Index 1";
// Read index 1.
Console.WriteLine(my_array[1]);

To access all array indexes in order, use a standard for loop.

for (int index = 0; index < my_array.Length; index++)
{
    Console.WriteLine(my_array[index]);
}

Dictionaries

Dictionaries can be incredibly powerful. See Dictionaries for more info.

Declaring Dictionaries

Similarly to C# arrays, once the data type is declared in a dictionary, it cannot be changed. However, note that "keys" and "values" in a dictionary can each hold a different, unique data type.

For example, to declare a dictionary of string keys and int values, use:

Dictionary<string, int> my_dict = new Dictionary<string, int>();

Accessing Dictionary Values

To set new key-value pairs, use:

my_dict.Add(<key>, <value>);

To read an existing key-value pair, use:

my_dict[<key>]

To update an existing key-value pair, use:

my_dict[<key>] = <updated_value>;

To remove an existing key-value pair, use:

 my_dict.Remove(<key>);

Example

Here's an example of a dictionary for a hypothetical business trying to track count of items sold.

// Create our dict.
Dictionary<string, int> product_sold = new Dictionary<string, int>();
 
// Add initial values.
product_sold.Add("Ice Cream", 50);
product_sold.Add("Burgers", 56);
product_sold.Add("Pizza", 102);
 
// Sold another pizza. Update value.
product_sold["Pizza"] += 1;

Structs

Structs are essentially a means to group sets of variables together. They are handled very similarly to C structs.

Unlike C# arrays or dicts, structs are able to combine as many variable types as desired.

Struct Declaration

First, declare the struct type itself.
If familiar with classes, this will look a lot like declaring a simplified class that has only class variables and nothing else.

struct MyStructObject
{
    public bool test_bool;
    public int test_int;
    public string test_string;
}

Once the struct type is declared, we can create instances of it to use.

MyStructObject a_struct = new MyStructObject();

Accessing Struct Items

Structs are basically containers for holding the associated variables within. Thus, we can easily access the contained variables with syntax that should look fairly familiar.

// Set or update struct values.
a_struct.test_bool = true;
a_struct.test_int = 5;
a_struct.test_string = "My test string"; 
 
// Print struct values.
Console.WriteLine(a_struct.test_bool);
Console.WriteLine(a_struct.test_int);
Console.WriteLine(a_struct.test_string);


Classes

A class can be thought of as a struct that can have functions built into it.

Classes are generally defined in new, separate files. A good rule of thumb is to only include multiple classes in one file if they are nested, inner subclasses within the first class.

Note: In C#, class variables and methods are often called with this.<value>, to help differentiate between local and class level values. However, this is optional and will not always be followed.

Class Variables

To declare class level variables, declare the variable name and type in the class, but don't assign to it.

For organization, it's recommended to do this at the very top of the class, and enclose it within a region.

class MyClass
{
    #region Variables
     
    bool test_bool;
    int test_int;
    string test_string;
     
    #endregion Variables
     
    ...
}

Constructor

A constructor is essentially the logic that's ran on class instantiation.

To declare a constructor, declare a method with the same name as the class and public accessibility.

If your class needs to be able to handle multiple possible sets of passed arguments, then create one constructor for each.

For example, this is a constructor for a class that takes 0 arguments.

class MyClass
{
    ...
     
    public MyClass()
    {
         // Constructor logic here.
    }
     
    ...
}

Properties

Properties are a "safer" way to read (get) and update (set) class variables.

Effectively, properties are functions that handle a single variable, and allow for custom logic to clean/validate your variable before saving it to the class or returning it for use outside of the class.

Minimum property syntax (to both set and get) is as follows:

class MyClass
{
    #region Variables
     
    string test_string;
     
    #endregion Variables
     
    ...
     
    public string TestString
    {
        get { return this.test_string; }
        set { this.test_string = value; }
    }
     
    ...
}

If we want to expand this to show how it can be useful, we can validate our value first.

class MyClass
{
    #region Variables
     
    string test_string;
     
    #endregion Variables
     
    ...
     
    public string TestString
    {
        get
        {
            // First check if our string is a known bad value.
            if (this.test_string == "I'm an invalid value, ohno!")
            {
                // Invalid value detected! Return something else as a fallback.
                return "Default string value."
            } else
            {
                // If we got here, then the string is valid. Return that.
                return this.test_string;
            }
        }
        set
        {
            // Check if our provided value is valid before setting.
            // In this case, we simply make sure it's 3 characters or greater.
            if (this.test_string.Length > 2)
            {
                this.test_string = value;
            }
        }
    }
     
    ...
}

Class Functions

Class functions are declared and handled the same way as any other C# function. See functions section.