skype: pavel.nasovich
email: forcewake@gmail.com
C# Version | Major Feature |
---|---|
C# 2.0 | Generics |
C# 3.0 | LINQ, Expression Trees |
C# 4.0 | Dynamics, Named/Optional Parameters, TPL |
C# 5.0 | Async/Await |
C# Version | Major Feature |
---|---|
C# 2.0 | Generics |
C# 3.0 | LINQ |
C# 4.0 | Dynamics, Named/Optional Parameters |
C# 5.0 | Async/Await |
C# 6.0 | Minor syntactic sugar! |
public async Task<string> ToTheInternet(string url)
{
string result = "";
try
{
HttpClient client = new HttpClient();
result = await client.GetStringAsync(url);
}
catch (Exception ex)
{
await LogToRemoteService(ex.Message);
}
return result;
}
Before
After
public Vector2D RotateVector(Vector2D v, double angle)
{
return new Vector2D()
{
X = v.X * Math.Cos(angle) - v.Y * Math.Sin(angle),
Y = v.X * Math.Sin(angle) + v.Y * Math.Cos(angle),
};
}
using System.Math;
public Vector2D RotateVector(Vector2D v, double angle)
{
return new Vector2D()
{
X = v.X * Cos(angle) - v.Y * Sin(angle),
Y = v.X * Sin(angle) + v.Y * Cos(angle),
};
}
Before
After
public void EatSandwich(Sandwich sandwich)
{
if(sandwich == null)
{
throw new ArgumentNullException("sandwich");
}
Digest(sandwich);
}
public void EatSandwich(Sandwich sandwich)
{
if (sandwich == null)
{
throw new ArgumentNullException(nameof(sandwich));
}
Digest(sandwich);
}
Before
After
public void InitCats()
{
this.Cats = new Dictionary<string, Cat>()
{
{ "PianoCat", new PianoCat()},
{ "CeilingCat", new CeilingCat()},
{ "MonorailCat", new MonorailCat()},
{ "LongCat", new LongCat()}
};
}
public void InitCats()
{
this.Cats = new Dictionary<string, Cat>()
{
["PianoCat"] = new PianoCat(),
["CeilingCat"] = new CeilingCat(),
["MonorailCat"] = new MonorailCat(),
["LongCat"] = new LongCat()
};
}
This results in a run-time ArgumentException
This results in a Dictionary with one key-value pair
public void InitCats()
{
this.Cats = new Dictionary<string, Cat>()
{
{ "LongCat", new LongCat()}
{ "LongCat", new TacGnol()}
};
}
public void InitCats()
{
this.Cats = new Dictionary<string, Cat>()
{
["LongCat"] = new LongCat(),
["LongCat"] = new TacGnol()
};
}
Before
After
public class CannedPeachFactory
{
public int NumPeaches { get; private set; }
private int numPeachesForMe;
public int NumPeachesForMe { get { return numPeachesForMe; } }
public CannedPeachFactory()
{
NumPeaches = 3;
numPeachesForMe = 300000000;
}
}
public class CannedPeachFactory
{
public int NumPeachesForMe { get; }
public CannedPeachFactory()
{
NumPeachesForMe = 300000000;
}
}
Before
After
public class CannedPeachFactory
{
public int NumPeaches { get; set; }
public CannedPeachFactory()
{
NumPeaches = 300000000;
}
}
public class CannedPeachFactory
{
public int NumPeaches { get; set; } = 300000000;
public CannedPeachFactory()
{
}
}
Before
After
public class lolcat
{
public List<FoodItem> Food { get; } = new List<FoodItem>();
public bool HasCheezburger
{
get
{
return Food.Any(x => x is Cheezburger);
}
}
}
public class lolcat
{
public List<FoodItem> Food { get; } = new List<FoodItem>();
public bool HasCheezburger => Food.Any(x => x is Cheezburger);
}
Before
After
public class Me
{
public List<Pokeman> Pokemans { get; } = new List<Pokeman>();
public void Show()
{
Console.WriteLine(String.Join(", ", Pokemans));
}
}
public class Me
{
public List<Pokeman> Pokemans { get; } = new List<Pokeman>();
public void Show() => Console.WriteLine(String.Join(", ", Pokemans));
}
Before
After
public string FillIn(string verb, string adjective1, string adjective2)
{
return String.Format("I {0} Mad Libs because they are {1} and {2}",
verb,
adjective1,
adjective2);
}
public string FillIn(string verb, string adjective1, string adjective2)
{
return $"I {verb} Mad Libs because they are {adjective1} and {adjective2}";
}
Before
After
public int GetNumOwnedBases(Organization org, BaseOwner owner)
{
int ownedBases = 0;
if (org != null && org.Bases != null)
{
ownedBases = org.Bases.Count(b => b.Owner == owner);
}
return ownedBases;
}
public int GetNumOwnedBases(Organization org, BaseOwner owner)
{
int? ownedBases = org?.Bases?.Count(b => b.Owner == owner);
return ownedBases ?? 0;
}
After - Even more succinct
public int GetNumOwnedBases(Organization org, BaseOwner owner)
{
return org?.Bases?.Count(b => b.Owner == owner) ?? 0;
}
public int GetNumOwnedBases(Organization org, BaseOwner owner)
{
int? ownedBases = org?.Bases?.Count(b => b.Owner == owner);
return ownedBases ?? 0;
}
After
Also works with indexers
public void MoveZIG(Armada armada)
{
int bound = armada?.ZIGs?.Count ?? 0;
for (int i = 0; i < bound; i++)
{
armada?.ZIGs?[i]?.Move();
}
}
Before
After - Ideal scenario
public class ZIG
{
public event EventHandler MainScreenTurnOn;
public void OnMainScreenTurnOn()
{
EventHandler localCopy = MainScreenTurnOn;
if (localCopy != null)
{
localCopy(this, EventArgs.Empty);
}
}
}
public class ZIG
{
public event EventHandler MainScreenTurnOn;
public void OnMainScreenTurnOn()
{
MainScreenTurnOn?(this, EventArgs.Empty);
}
}
Ideal scenario is not allowed - DelegateName?() is illegal
public class ZIG
{
public event EventHandler MainScreenTurnOn;
public void OnMainScreenTurnOn()
{
MainScreenTurnOn?(this, EventArgs.Empty);
}
}
Legal - DelegateName?.Invoke()
public class ZIG
{
public event EventHandler MainScreenTurnOn;
public void OnMainScreenTurnOn()
{
MainScreenTurnOn?.Invoke(this, EventArgs.Empty);
}
}
Modular implementation of the .NET Framework
Open source
Designed for agile deployment over NuGet
Designed to be the a la carte base stack for different environments (desktop, phone, web, etc.)
Does not yet fully cover all the APIs spanned by .NET Framework; this set will get smaller over time.
Codename "Roslyn"
dotnet new dotnet restore dotnet run
May 2014
ASP.NET vNext announced
February 2015
ASP.NET 5 announced
November 2015
ASP.NET 5 and .NET Core RC 1
January 2016
ASP.NET Core and .NET Core RC 2
June 2016
ASP.NET Core and .NET Core 1.0
dnvm dnx dnu
A Web service, in very broad terms, is a method of communication between two applications or electronic devices over the World Wide Web (WWW).
Web services are of two kinds: Simple Object Access Protocol (SOAP) and Representational State Transfer (REST).
public interface ICustomeRepository
{
Customer GetCustomerById(Guid id);
IEnumerable<Customer> SearchCustomersByName(string name);
IEnumerable<Customer> SearchCustomersByNameAndRegion(string name, Region region);
IEnumerable<Customer> GetActiveCustomers();
IEnumerable<Customer> GetCustomersByPricingLevel(PricingLevel pricingLevel);
IEnumerable<Customer> GetCustomersByPricingLevel(PricingLevel pricingLevel, bool active);
IEnumerable<Customer> GetCustomersByRegion(Region region);
IEnumerable<Customer> GetCustomersByRegion(Region region, bool active);
IEnumerable<Customer> GetCustomersByRegionAndPricingLevel(
Region region,
PricingLevel pricingLevel);
IEnumerable<Customer> GetCustomersByRegionAndPricingLevel(
Region region,
PricingLevel pricingLevel,
bool active);
}
public class ChangeCustomerPricingLevel : IAsyncRequest
{
public Guid CustomerId { get; }
public PricingLevel PricingLevel { get; }
public ChangeCustomerPricingLevel(Guid customerId, PricingLevel pricingLevel)
{
CustomerId = customerId;
PricingLevel = pricingLevel;
}
}
Commands & Queries
public class ChangePricingLevelHandler : IAsyncRequestHandler<ChangeCustomerPricingLevel, Unit>
{
private CustomerContext _db;
public ChangePricingLevelHandler(CustomerContext db)
{
_db = db;
}
public async Task<Unit> Handle(ChangeCustomerPricingLevel message)
{
var customer = _db.Customers.Single(x => x.CustomerId == message.CustomerId);
customer.PrivingLevel = message.PricingLevel;
await _db.SaveChangesAsync();
return Unit.Value;
}
}