- Create a folder
- Open the folder in VSCode
- Run the following command:
dotnet new console
To run the app:
Either,
- F5
Or,
- In the VSCode Terminal:
dotnet run
To compile a Release build:
dotnet run -c Release
using System;
namespace MyNamespace
{
public abstract class MySuperClass
{
public MySuperClass()
{
}
public abstract void Output();
}
public class MySubClass : MySuperClass
{
private int val;
public MySubClass(int val = 5)
{
this.val = val;
}
public override void Output()
{
Console.WriteLine($"{this.val}");
}
}
class Program
{
static void Main(string[] args)
{
MySuperClass myClass = new MySubClass();
myClass.Output(); // output 5
myClass = new MySubClass(10);
myClass.Output(); // output 10
}
}
}
using System;
namespace MyNamespace
{
public struct MyStruct1
{
public int x;
public int y;
}
public struct MyStruct2
{
public MyStruct2(int x, int y)
{
this.x = x;
this.y = y;
}
public int x;
public int y;
}
class Program
{
static void Main(string[] args)
{
MyStruct1 myStruct1 = new MyStruct1();
myStruct1.x = 5;
myStruct1.y = 6;
Console.WriteLine($"{myStruct1.x}, {myStruct1.y}"); // output: 5, 6
MyStruct2 myStruct2 = new MyStruct2(7, 8);
Console.WriteLine($"{myStruct2.x}, {myStruct2.y}"); // output: 7, 8
}
}
}
using System;
namespace MyNamespace
{
enum MyEnum
{
Val1, // 0
Val2, // 1
Val3 = 6, // 6
Val4, // 7
Val5, // 8
Val6 // 9
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyEnum.Val2); // output: Val2
int val = (int)MyEnum.Val2; // enum to int conversion
Console.WriteLine(val); // output: 1
var en = (MyEnum)8; // int to enum conversion
Console.WriteLine(en); // output: Val5
}
}
}
NOTE: Once a case matches, all statements following that case (including other cases!) will be executed until a break
or return
statement is encountered.
It should also be noted, however, that leaving out break
statements is generally considered bad practice.
using System;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
int x = 10;
switch (x)
{
case 5:
Console.WriteLine("Value of x is 5");
break;
case 10:
Console.WriteLine("Value of x is 10");
break;
case 15:
// if there is no break statement
// both "15" and "20" will trigger
// the "20" case
case 20:
Console.WriteLine("Value of x is 15 or 20");
break;
default:
Console.WriteLine("Unknown value");
break;
}
}
}
}
using System;
namespace MyNamespace
{
public class MyClass
{
public MyClass()
{
}
public void TriggerEvent()
{
Changed(10);
}
public event Action<int> Changed;
}
class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Changed += ChangeHandler;
myClass.TriggerEvent(); // output: 10
}
static void ChangeHandler(int val)
{
Console.WriteLine($"{val}");
}
}
}
String Formatter:
Console.WriteLine(string.Format("{0} & {1}", var1, var2));
String Interpolation:
Console.WriteLine($"{var1} & {var2}");
Displaying Bytes
To display the bytes for a number, use: Convert.ToString(num, toBase: 2)
using System;
using System.Text.Json;
public class Car
{
public string Model
{
get { return "Volkswagon"; }
}
public string Make
{
get { return "Golf"; }
}
public CarDetails Details
{
get { return new CarDetails(); }
}
}
public class CarDetails
{
public int Year
{
get { return 2017; }
}
public float Price
{
get { return 20000f; }
}
public Condition Condition
{
get { return Condition.EXCELLENT; }
}
}
public enum Condition
{
EXCELLENT,
GOOD,
POOR
}
class Program
{
static void Main()
{
Car car = new Car();
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(JsonSerializer.Serialize(car, typeof(Car), options));
// Output:
// {
// "Model": "Volkswagon",
// "Make": "Golf",
// "Details": {
// "Year": 2017,
// "Price": 20000,
// "Condition": 0
// }
// }
}
}
Generally, the two fastest ways to check the parity of a number (whether it is even or odd) are the following:
Using bitwise &
This is normally the fastest method.
Checks if the last binary digit of the number is 1 (in which case it is odd).
private static bool isEven(int i)
{
return (i & 1) == 0;
}
Testing the remainder
This can be easiest to read.
Checks if there is any remainder after dividing by 2 (in which case it is odd).
private static bool isEven(int i)
{
return (i % 2) == 0;
}
To achieve an even distribution of HashCodes, the following technique is generally used:
- Combine the properties used to test for equality (i.e. in
Equals()
). - Add some prime numbers to improve the distribution.
There are several approaches to achieve this:
Method 1: XOR and Primes
public sealed class Point3D
{
private readonly double x;
private readonly double y;
private readonly double z;
private readonly ReadOnlyCollection<string> attrs;
public Point3D(double x, double y, double z, IEnumerable<string> attrs)
{
this.x = x;
this.y = y;
this.z = z;
this.attrs = new ReadOnlyCollection<string>(attrs.ToList());
}
public double X => this.x;
public double Y => this.y;
public double Z => this.z;
public ReadOnlyCollection<string> Attrs => this.attrs;
public override bool Equals(object other)
{
return other is Point3D p
&& p.X == X
&& p.Y == Y
&& p.Z == Z
&& p.Attrs == Attrs; // simplified for brevity
}
public override int GetHashCode()
{
unchecked // Allow arithmetic overflow, numbers will just "wrap around"
{
int hashcode = 1430287;
hashcode = hashcode * 7302013 ^ X.GetHashCode();
hashcode = hashcode * 7302013 ^ Y.GetHashCode();
hashcode = hashcode * 7302013 ^ Z.GetHashCode();
hashcode = hashcode * 7302013 ^ Attrs.GetHashCode();
return hashcode;
}
}
}
Method 2: Use a Tuple
With the introduction of tuples in C# 7, this can be simplified to the following:
public sealed class Point3D
{
private readonly double x;
private readonly double y;
private readonly double z;
private readonly ReadOnlyCollection<string> attrs;
public Point3D(double x, double y, double z, IEnumerable<string> attrs)
{
this.x = x;
this.y = y;
this.z = z;
this.attrs = new ReadOnlyCollection<string>(attrs.ToList());
}
public double X => this.x;
public double Y => this.y;
public double Z => this.z;
public ReadOnlyCollection<string> Attrs => this.attrs;
public override bool Equals(object other)
{
return other is Point3D p
&& p.X == X
&& p.Y == Y
&& p.Z == Z
&& p.Attrs == Attrs; // simplified for brevity
}
public override int GetHashCode() => (X, Y, Z, Attrs).GetHashCode();
}
Method 2: Helper Struct
This following approach is taken from Rehan Saeed’s “GetHasCode Made Easy”:
- https://rehansaeed.com/gethashcode-made-easy/
// MIT Licensed
// Copyright (c) 2019 Muhammad Rehan Saeed
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
/// <summary>
/// A hash code used to help with implementing <see cref="object.GetHashCode()"/>.
/// </summary>
public struct HashCode : IEquatable<HashCode>
{
private const int EmptyCollectionPrimeNumber = 19;
private readonly int value;
/// <summary>
/// Initializes a new instance of the <see cref="HashCode"/> struct.
/// </summary>
/// <param name="value">The value.</param>
private HashCode(int value) => this.value = value;
/// <summary>
/// Performs an implicit conversion from <see cref="HashCode"/> to <see cref="int"/>.
/// </summary>
/// <param name="hashCode">The hash code.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator int(HashCode hashCode) => hashCode.value;
/// <summary>
/// Implements the operator ==.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HashCode left, HashCode right) => left.Equals(right);
/// <summary>
/// Implements the operator !=.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HashCode left, HashCode right) => !(left == right);
/// <summary>
/// Takes the hash code of the specified item.
/// </summary>
/// <typeparam name="T">The type of the item.</typeparam>
/// <param name="item">The item.</param>
/// <returns>The new hash code.</returns>
public static HashCode Of<T>(T item) => new HashCode(GetHashCode(item));
/// <summary>
/// Takes the hash code of the specified items.
/// </summary>
/// <typeparam name="T">The type of the items.</typeparam>
/// <param name="items">The collection.</param>
/// <returns>The new hash code.</returns>
public static HashCode OfEach<T>(IEnumerable<T> items) =>
items == null ? new HashCode(0) : new HashCode(GetHashCode(items, 0));
/// <summary>
/// Adds the hash code of the specified item.
/// </summary>
/// <typeparam name="T">The type of the item.</typeparam>
/// <param name="item">The item.</param>
/// <returns>The new hash code.</returns>
public HashCode And<T>(T item) =>
new HashCode(CombineHashCodes(this.value, GetHashCode(item)));
/// <summary>
/// Adds the hash code of the specified items in the collection.
/// </summary>
/// <typeparam name="T">The type of the items.</typeparam>
/// <param name="items">The collection.</param>
/// <returns>The new hash code.</returns>
public HashCode AndEach<T>(IEnumerable<T> items)
{
if (items == null)
{
return new HashCode(this.value);
}
return new HashCode(GetHashCode(items, this.value));
}
/// <inheritdoc />
public bool Equals(HashCode other) => this.value.Equals(other.value);
/// <inheritdoc />
public override bool Equals(object obj)
{
if (obj is HashCode)
{
return this.Equals((HashCode)obj);
}
return false;
}
/// <summary>
/// Throws <see cref="NotSupportedException" />.
/// </summary>
/// <returns>Does not return.</returns>
/// <exception cref="NotSupportedException">Implicitly convert this struct to an <see cref="int" /> to get the hash code.</exception>
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() =>
throw new NotSupportedException(
"Implicitly convert this struct to an int to get the hash code.");
private static int CombineHashCodes(int h1, int h2)
{
unchecked
{
// Code copied from System.Tuple so it must be the best way to combine hash codes or at least a good one.
return ((h1 << 5) + h1) ^ h2;
}
}
private static int GetHashCode<T>(T item) => item?.GetHashCode() ?? 0;
private static int GetHashCode<T>(IEnumerable<T> items, int startHashCode)
{
var temp = startHashCode;
var enumerator = items.GetEnumerator();
if (enumerator.MoveNext())
{
temp = CombineHashCodes(temp, GetHashCode(enumerator.Current));
while (enumerator.MoveNext())
{
temp = CombineHashCodes(temp, GetHashCode(enumerator.Current));
}
}
else
{
temp = CombineHashCodes(temp, EmptyCollectionPrimeNumber);
}
return temp;
}
}
This can then be used in the following manner:
public sealed class Point3D
{
private readonly double x;
private readonly double y;
private readonly double z;
private readonly ReadOnlyCollection<string> attrs;
public Point3D(double x, double y, double z, IEnumerable<string> attrs)
{
this.x = x;
this.y = y;
this.z = z;
this.attrs = new ReadOnlyCollection<string>(attrs.ToList());
}
public double X => this.x;
public double Y => this.y;
public double Z => this.z;
public ReadOnlyCollection<string> Attrs => this.attrs;
public override bool Equals(object other)
{
return other is Point3D p
&& p.X == X
&& p.Y == Y
&& p.Z == Z
&& p.Attrs == Attrs; // simplified for brevity
}
public override int GetHashCode()
{
return HashCode
.Of(this.X)
.And(this.Y)
.And(this.Z)
.AndEach(this.Attrs);
}
}