Auto properties
set vs private set
- La variable que está como
public ... { get; set; }
se puede llamar de manera externa e interna. - Mientras que la variable
public ... { get; private set; }
se puede hacer unget
de manera externa pero no se puede hacerset
de manera externa
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; }
Herencia
Para heredar una clase y varias interfaces desde otra, primero se pone la clase y luego las interfaces.
public class Example : AnotherClass, IExample
{
}
Exceptions
How to create your custom Exception
public class MyException : ApplicationException
{
public MyException() : base("This is my custom exception")
{
}
}
Generics
Usage
public class GenericList<T>
{
public void Add(T input)
{
}
}
Interfaces
Ejemplo de implementacion
interface IEquatable<T>
{
bool Equals(T obj);
}
Classes vs Structs
Ambas son muy similares. En su definición sólo cambia la keyword struct
.
La diferencia es que las clases son tipos por referencia. Las estructuras son tipos por valor.
Las estructuras pueden trabajar como clases pero realmente son valores ubicados directamente en la pila y no referencias a la informacion que hay en memoria. Para matrices, listas o pilas de miles de clases, las estructuras son más eficientes porque no necesita crear la referencia.
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
public struct PointStruct
{
public int X { get; set; }
public int Y { get; set; }
}
(!) Atención ya que su uso cambia (!)
Para el ejemplo anterior, tenemos el siguiente código:
Class:
static void Main(string[] args)
{
Point punto = new Point();
punto.X = 10;
punto.Y = 8;
SumaCoordenadas(punto);
// X = 20; Y = 18;
}
static void SumaCoordenadas(Point punto)
{
point.X = point.X + 10;
point.Y = point.Y + 10;
}
Struct:
static void Main(string[] args)
{
PointStruct puntoStruct = new PointStruct();
puntoStruct.X = 10;
puntoStruct.Y = 8;
SumaCoordenadas(puntoStruct);
// X = 10; Y = 8;
}
static void SumaCoordenadas(PointStruct puntoStruct)
{
point.X = point.X + 10;
point.Y = point.Y + 10;
}
Tipos de Acceso
internal: 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: Mezcla de protected con internal.
Abstract class
Clase abstracta
public abstract class Vehiculos
{
public void Mover()
{
Console.WriteLine("Moviendo {0} ruedas", Ruedas);
}
public abstract int Ruedas { get; }
}
Ejemplo de implementacion
public class Coche : Vehiculos
{
public override int Ruedas
{
get { return 4; }
}
}
Abstract vs Virtual
(Check this https://stackoverflow.com/questions/391483/what-is-the-difference-between-an-abstract-method-and-a-virtual-method and this https://stackoverflow.com/questions/14728761/difference-between-virtual-and-abstract-methods)
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: https://stackoverflow.com/questions/54098375/expression-bodied-members-vs-lambda-expressions)
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));
}
Example3 (constructors)
Otro ejemplo para constructores:
original constructor
public Student(string name, string surname, int age)
{
Name = name;
Surname = surname;
Age2 = age;
}
expression bodied syntax:*
public Student(string name, string surname, int age) => (Name, Surname, Age2) = (name, surname, age);
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;