Auto properties
set vs private set
- La variable que está como
public x { get; set; }
se puede llamar de manera externa e interna. - Mientras que la variable
public x { get; private set; }
se puede hacer unget
de manera externa pero no unset
ejemplo
public class Person
{
public string Name { get; set; }
public string Surname { get; private set; }
public Person()
{
Name = "ctor name";
Surname = "ctor surname";
}
public void SetInternalValues()
{
Name = "name internal value";
// if we'd have public string Surname { get; } without set;
// then we couldn't set Surname inside its own class either
Surname = "surname internal value";
}
}
var person = new Person();
person.Name = "name external value";
// person.Surname = "this isn't possible"; // cannot be set as we use { private set; }
Exceptions
How to create your custom Exception
public class MyException : ApplicationException
{
public MyException() : base("This is my custom exception")
{
}
}
Classes vs Structs
Please check this post on class
vs struct
vs record
.
Tipos de Acceso
internal: Visible solo dentro del mismo ensamblado. Útil para ocultar detalles de implementación que no deben ser públicos fuera de una libreria.
Desde el mismo proyecto se tiene acceso, como si fuera public. Desde fuera del ensamblado (exportada como libreria) no se tiene acceso, como si fuera private.
protected internal: Más accesible que internal
. Accesible o bien desde el mismo enamblado o bien desde una subclase hija.
Abstract class
Clase abstracta
public abstract class Vehiculos
{
public void Mover()
{
Console.WriteLine($"Moviendo {Ruedas} ruedas");
}
public abstract int Ruedas { get; }
}
Ejemplo de implementacion
public class Coche : Vehiculos
{
public override int Ruedas
{
get { return 4; }
}
}
Abstract vs Virtual
(For more information on the topic check this and also this one)
An abstract
function cannot have functionality. Any child class must implement their own version of this method, however it’s too general to even try to implement in the parent class.
A virtual
function implements a default solution but you can override it in a child class. Even then, you can still call the parent method.
public abstract class E
{
public abstract void AbstractMethod(int i);
public virtual void VirtualMethod(int i)
{
// Default implementation, which can be overriden.
}
}
public class D : E
{
public override void AbstractMethod(int i)
{
// You HAVE TO override this method.
}
public override void VirtualMethod(int i)
{
// You can delete this if you want and use parent's version.
}
}
Sealed Class
Las clases marcadas como sealed
no se pueden usar como clase base. No se pueden usar para heredar. Por esta razón no pueden ser abstract
.
public sealed class SealedClass
{
}
Extension methods
Es posible extender funcionalidad que echemos en falta a clases como string
. Para ello se crea un extended method y desde donde lo queramos llamar solo hay que añadir el import.
extended method declaration
public static class MyExtension
{
public static int WordCount(this string str)
{
return str.Split(new char[] { ' ', '.', '?'}),
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
usage
// (import)
static void Main(string[] args)
{
string s = "Hello World";
int i = s.WordCount();
}
Expression bodied members
(Check this for more information)
We can use expression-bodied syntax to implement a shorter syntax for properties and (named) methods (syntactic sugar). This has nothing to do with Lambdas.
Example (ToString)
original method
public override string ToString()
{
return $"{FullName}, {Age}";
}
expression-bodied syntax
public override string ToString() => $"{FullName}, {Age}";
Example2 (getters)
Otra variacion se puede usar para comprobaciones en getters y setters.
expression-bodied syntax
private int age;
public int Age2
{
get => age;
set => age = value > 0 ? value : throw new ArgumentOutOfRangeException(nameof(value));
}
Destructores
Se ejecutan cuando CLR destruye los objetos de la clase. Se ejecuta cuando el recolector de basura limpia de una manera automática.
public class Punto
{
// constructor
public Punto()
{
}
// destructor
~Punto()
{
}
}
Sobrecarga de operadores
Es posible sobrecargar operadores para que operen con clases (sumar o restar clases).
definition
public class Punto
{
// adds 1 whenever the operator '+' is used.
public static Punto operator + (Punto valor)
{
Punto nuevoPunto = new Punto();
nuevoPunto.X = valor.X + 1;
nuevoPunto.Y = valor.Y + 1;
return nuevoPunto;
}
}
usage
Punto punto = new Punto(200, 50);
punto = +punto;