- Should be named with Pascal Case
public class Customer
{
...
public Customer()
{
Orders = new List<Order>();
}
public Customer(int id) {
this.Id = id;
}
public Customer(int id, string name)
: this(id)
{
this.Name = name;
}
}
: this()calls the first constructor before the overloaded one- Should be used minimally, as adds complexity to control flow
- Syntax for quickly initializing an object without the need to call one of its constructors
var person = new Person {
FirstName = "Miller",
LastName = "Anderson"
};
public class Calculator
{
public int Add(params int[] numbers){}
}
var result = calculator.Add(new int[]{ 1, 2, 3, 4 });
var result = calculator.Add(1, 2, 3, 4);
- Should be avoided when possible due to 'code smell' (Mosh' opinion)
public class Weirdo
{
public void DoAWeirdThing(ref int a)
{
a += 2;
}
}
var a = 1;
weirdo.DoAWeirdThing(ref a); // a = 3;
- Should be avoided when possible due to 'code smell' (Mosh' opinion)
public class MyClass
{
public void MyMethod(out int result)
{
result = 1;
}
}
int a;
myClass.MyMethod(out a); // a = 1
- Variables stored at class level
public class Customer
{
public List<Order> orders = new List<Order>();
}
- Can be initialized at class level without need for constructor
public class Customer
{
readonly List<Order> orders = new List<Order>();
}
A way to control access to a class and / or its members
- Public
- Accessible from everywhere
- Private
- Accessible from only the class
- Protected
- Accessible only from the class and its derived / child classes
- Internal
- Accessible only from the same assembly (or class library)
- Protected Internal
- Accessible only from the same assembly or any derived classes
- Rarely used
- A class member that encapsulates a getter/setter for accessing a field
public class Person
{
private DateTime _birthdate;
public DateTime Birthdate
{
get { return _birthdate;}
set { _birthdate = value; }
}
}
public class Person
{
public DateTime Birthdate { get; set; }
}
- Internally creates a private field
var array = new int[5];
array[0] = 1;
var list = new List<int>();
list[0] = 1;
var cookie = new HttpCookie();
cookie.Expire = DateTime.Today.AddDays(5);
cookie["name"] = "Miller";
// Preferable over:
cookie.SetItem("name", "Miller");
public class HttpCookie
{
public string this[string key]
{
get { ... }
set { ... }
}
}
- Use a
Dictionary<>in instances where data lookup depends on akey - Use
List<>in instances where data lookup depends onindex
- A measure of how interconnected classes and subsystems are
- A kind of relationship between two classes that allows one to inherit code from another
- Have an 'Is-A' relationship:
- A Car is a Vehicle
- Code re-use
- Polymorphic behavior
- A kind of relationship between two classes that allows one to contain the other
- Have a 'Has-A' relationship:
- A Car has an Engine
- Flexibility
- A means to loose-coupling
- Easily abused by amateur designers / developers
- Large hierarchies
- Fragility
- Tight coupling
- Any inheritance relationship can be translated to composition
- Flexibility and loose coupling
- Base class constructors are always executed first
- Base class constructors are not inherited
public class Car : Vehicle
{
public Car(String registrationNumber)
: base(registrationNumber)
{
// Initialize fields specific to the car class
}
}
- Invokes the constructor of the parent class (in this case,
Vehicle)
- Conversion from a derived class to a base class (upcasting)
- Conversion from a base class to a derived class (downcasting)
Circle circle = new Circle();
Shape shape = circle;
- No conversion necessary
Circle circle = new Circle();
Shape shape = circle;
Circle anotherCircle = (Circle)shape;
- Used to cast an object as another without throwing a
CastExceptionError
Car car = obj as Car;
if (car != null)
{
...
}
- Used to verify the type of an object
if (obj is Car)
{
...
}
- Have a performance penalty
- Stored on the stack (shorter lifespan / less memory)
- All primitive types
- Stored in the heap (longer lifespan / more memory)
- Any classes
- The process of converting a value type instance to an object reference
int number = 10;
object obj = number;
// or
object obj = 10;
object obj = 10;
int number = (int)obj;
- Modifying the implementation of an inherited method
- Used in polymorphism
public class Shape
{
public virtual void Draw()
{
// Default implementation
}
}
public class Circle : Shape
{
public override void Draw()
{
// New implementation
}
}
- Indicates that a class or member is missing implementation
public abstract class Shape
{
public abstract void Draw();
}
public class Circle : Shape
{
public override void Draw()
{
// Implementation for Circle
}
}
- Classes with
abstractmembers must also be declared asabstract - Do not include implementation
- Must implement all abstract members from base abstract class
- When you want to provide some common behavior while forcing other developers to follow your design
- Opposite of abstract classes
- Prevents derivation of classes or overriding methods
- (rarely used)
- Slightly faster because of some run-time optimization
- A language construct similar to a class (syntactically) but is fundamentally different
- No access modifiers
- Think of an interface as a contract whose methods and properties must be implemented
public interface ITaxCalculator
{
int Calculate();
}
public class TaxCalculator : ITaxCalculator
{
public int Calculate(order){
...
}
}
- Read as TaxCalculator implements ITaxCalculator
- Not the same as inheritance
- To build loosely-coupled applications
- Improve extensibility and testability of applications
- Promote loose-coupling between concrete classes that are dependent (inherit) another
- When unit testing classes, if that class has dependencies on other concrete classes, you can use an interface to reduce that coupling
METHODNAME_CONDITION_EXPECTATION
- Pattern for naming test methods
- THEORY - Extensibility allows for changing behavior of existing classes without changing said classes -- create new classes that implement desired behavior, that are referred to in concrete class
public class ConsoleLogger : ILogger
{
public void logError(string message)
{
Console.WriteLine(message);
}
public void LogInfo(string message)
{
Console.WriteLine(message);
}
}
public class DbMigrator
{
private readonly ILogger _logger;
public DbMigrator(ILogger logger)
{
_logger = logger;
}
public void Migrate()
{
_logger.LogInfo("Migrating started at " + DateTime.Now);
// ... details of migrating database
_logger.LogInfo("Migrating finished at " + DateTime.Now);
}
}
- Software applications should be open for extensibility but closed for modification
- Don't Repeat Yourself
- Classes can implement multiple interfaces, not inherit them

