Visual Studio 15 Preview ile C# 7.0 Yeniliklerini İnceleme
Selamlar,
Bugün Visual Studio 15 Preview’da C# 7.0 ile gelen ve henüz gelmeyen özellikleri örnek kod parçaları ile inceleyeceğiz.
1-) Öncelikle Visual Studio 15’in Visual Studio 2015’e göre %30 daha hızlı çalışacağı belirtiliyor.
2-) Visual Studio 15’de execute in Interactive özelliğinin gelmesi. İlgili kod parçacığı seçilip, sağ tıklanınca açılan menüden Excute in Interactive seçilince, ilgili kodlar Interactive penceresinde çalıştırılır ve uygulama derlenmeden seçilen kod parçacığının sonucu Interactive ekranına aşağıdaki gibi basılır.
3-) Local Functions: Önceki makalemden bu konu ile ilgili detaylı bilgi alabilirsiniz. Kısaca özetlemek gerekir ise, method içinde method tanımlamayı yarıyan bir yapıdır.
Not: Bu yeni özelliklerin çalıştırılabilmesi için çalıştırılacak proje sağ tıklanıp, “Properties” sekmesinden soldaki kulakçıklardan “Build” seçilir. Aşağıda görüldüğü gibi Conditional compilation symbols kısmına “__DEMO__” yazılarak yeni özelliklerin hatasız bir şekilde derlenmesi sağlanır.
a-) Aşağıdaki örnekte Main methodu altında “Selector()” methodu tanımlanmış ve kendisine gelen string değişkenin “ToUpper()” ile büyütülmesi sağlanmıştır. Daha sonra Linq kullanılarak “words[]” string dizisi “select()” methodu ile çekilip içine aşağıda tanımlanan “Selector()” konulmuş ve tüm kelimelerin büyük olara ekrana basılması, yukarıda “Interactive” tanımlama ekranında görüldüğü gibi sağlanmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
static void Main(string[] args) { //Local functions String[] words = { "orange", "apple", "Article", "elephant", "star", "and" }; string Selector(string keyword) { return keyword.ToUpper(); } IEnumerable<String> aWords = words.Select(Selector); foreach (String word in aWords) Console.WriteLine(word); } |
b-) Aşağıdaki örnekte yine aynı “words[]” kelime dizisi “predicate()” methodu ile gelen string değerin “karakter uzunluğu” ile dizideki “index değeri“, yani sıra numarası eşit ise “true” değeri dönülmektedir. Buna göre ilgili kod çalıştırılınca sadece “star” değeri geri dönülmektedir. Çünkü “star” hem “4. sırada” hem de “4 karakter” uzunluğundadır.
1 2 3 4 5 6 7 8 9 10 11 12 |
static void Main(string[] args) { //Local functions String[] words = { "orange", "apple", "Article", "elephant", "star", "and" }; bool predicate(String str,int index) { return str.Length == index; } IEnumerable<String> aWords2 = words.Where(predicate).Select(str => str); foreach (String word2 in aWords2) Console.WriteLine(word2); } |
4-) Pattern matching : “Switch – Case” yapısında gelen değişken tiplerine göre farklı işlemler yapıla bilmektedir. Örneğin aşağıda generic bir değişken bekleyen bir method tanımlanmıştır. Gelen değişken tipine göre yani “string veya int’e” göre farklı operasyonlar yürütülmüştür. Bunun yerine gelen bir sınıf ya da interface tipine göre de farklı işlemler yapılabilirdi. Aşağıda örnek olarak, string “Bora” değişkenine göre alınan sonuç ekranı basılmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
T GetValue<T>(T nesne) { return nesne; } string obje = "Bora"; object v = GetValue(obje); switch (v) { case string s: Console.WriteLine($"{v} is a string of length {s.Length}"); break; case int i: Console.WriteLine($"{v} is an {(i % 2 == 0 ? "even" : "odd")} int"); break; default: Console.WriteLine($"{v} is something else"); break; } |
5-) Ref returns and ref locals : Burada amaç private değişkenleri olan bir sınıfın değerlerini gerektiği zaman “ref” keyword’ü ile değiştirebilmektir. Aşağıda görüldüğü gibi “ForVariables” sınıfına ait “x” ve “y” private değişkenleri vardır. “GetByRef()” methodu ile gelen string parametreye karşılık gelen değişken referance tipi ile birlikte geri dönülmektedir. İlkin “x” değişkeni dönülmüş ve 42 değeri atanmıştır. 2. durumda “y” değişkenine, “ForVariables”‘a ait “y” değişkeni referance değeri atanmış ve 99 değeri verilmiştir. Böylece “ForVariables()” sınıfına ait private “x,y” değişkenlerine sıra ile 42 ve 99 değerleri atanabilmiştir. ilk başta herhangi bir değer atanmadan”ToString()” methodu override edilerek çağrıldığında “0,0” değeri dönülür. İlgili değişkenlere “ref” ile değer atandığında “42,99” sonuçları console’da görülür.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
class FooVariables { private int x; private int y; public ref int GetByRef(string name) { if (name == "x") return ref x; if (name == "y") return ref y; throw new ArgumentException(nameof(name)); } public override string ToString() => $"{x},{y}"; } var foo = new FooVariables(); Console.WriteLine(foo); // 0, 0 foo.GetByRef("x") = 42; ref int y = ref foo.GetByRef("y"); y = 99; Console.WriteLine(foo); // 42, 99 |
Ekran çıktısı:
6-) Binary Literals ve Digit Separators : Aşağıda görüldüğü gibi 1 milyar değeri “_” seperetor’ü ile okunmayı kolaylaştırmak için ayrılmıştır. Ayrıca binary degerler artık direk değişkene atanabilmektedir. Örnek “foo2″‘ye ilgili degerler “0x7FFF_1234” şeklinde atılmaktadır. Ayrıca size örnek olması amacı ile zaten şu anda var olan gelen bir Binary Parametrenin string karşılığı bulunup ekrana basılmıştır. Böylece binary değişkenlerde seperetor’ün önemi gösterilmiştir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
int oneBillion = 1_000_000_000; Console.WriteLine("Big Number :" + oneBillion * 5); Byte[] GetBytesFromBinaryString(String binary) { var list = new List<Byte>(); for (int i = 0; i < binary.Length; i += 8) { String t = binary.Substring(i, 8); list.Add(Convert.ToByte(t, 2)); } return list.ToArray(); } int foo2 = 0x7FFF_1234; var data = GetBytesFromBinaryString("010000010100001001000011"); Console.WriteLine("Binary Deger: "+Encoding.ASCII.GetString(data)); int bar = 0b1001_0110_1010_0101; |
7-) Tuples: Bu konu ile ilgili detaylı bilgili önceki makalemden erişebilirsiniz. Bundan sonraki yazılan maddeler henüz derlenmemektedir. Ama muhtemelen bir sonraki Visual Studio 15 versiyonunda çalışacaktır. Tuple’da esas amaç, bir metohodun birden çok değer geri dönmesini sağlamaktır. Tuple’da en fazla 8 değişken geri dönülebilmekte ve geri dönüş tipinin Tuple olması durumunda yeni bir 8 değişken daha bu değişkenin içinde dönülebilmektedir. Dolayısı ile istenen sayıda değer geri dönülebilmektedir. Önceden Tuple’da esas sorun, dönülen değişkenlere direk ismi ile erişilemiyordu. Artık aynı bir sınıfın propertyleri gibi geri dönüş değişkenlerine erişilip, değerleri alınabilmektedir. Aşağıdaki örnekte birden fazla kişiden para toplanmıştır.”TotalMoney()” methodunda toplanan tüm para ve toplam para veren kişi sayısı bulunmakta ve geri dönülmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 |
public (int sum, int count) TotalMoney(IEnumerable<int> values) { sumMoney = 0; personCount = 0; foreach (var value in values) { sumMoney += value; personCount++; } return (sum, count); } int[] perMoney=new int[]{50,25,80,100}; List<int> moneyList=new List<int>(); moneyList.AddRange(perMoney); var t = TotalMoney(moneyList); var sum = t.Sum; var count = t.Count; |
8-)Non-Nullable Reference Types : Bu özellikle null olmasını istemediğimiz “string” değişkenlerin başına ünlem koyarak tanımlayabiliriz.
1 |
(string?) or avoid null (string!) |
9-)Records (or Record Types): Amaç propertyleri olan bir sınıfın, yaratılma anında değerlerinin tek satır ile atanmasıdır. “Method” ile karıştırılmasın. Geriye değer döndürme gibi bir durum söz konusu değildir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Cube { int _width; int _height; int _depth; MyPoint(int width, int height, int depth){ this._width = x; this._height = y; this._depth = z; } public int Width {get{ return this._width;}} public int Height {get{ return this._height;}} public int Depth {get{ return this._depth;}} } |
Sınıfın çağrılış şekli:
1 |
public class Cube(int Width, int Height, int Depth) |
10-)Immutable Types : Geldik benim için en fovori yeniliğe. Özellikle benzer özelliklerde sınıflar ile çalışılan yapılarda, gerçekten bir ilaç niteliğinde diyebilirim. Mesela bir oyun yapacağız ve benzer özelliklerde birçok karakter kullanacağız. Sınıfımız aşağıda görüldüğü gibi “Person“. Aynı soyada sahip 2. bir karakter yaratılacağı zaman, sadece değişen propertyler “with” ile tanımlanıp , ilgili person sınıfının diğer propertyleri miras olarak alınabilir. Böylece yeni bir “per2” adında “Person” sınıfı oluşturulurken, sadece değişen soyad tanımlanırken diğer benzer propertyleri tanımlanmaz. Böylece, kodlama anında büyük bir hız kazanılır.
1 2 3 4 5 6 7 8 9 10 |
public class Person { public Person(string name, string surname) { Name = name; SurName = surname; } public string Name { get; set; } public string SurName { get; set; } } |
1 2 |
Person per = new Person("Bora", "Kasmer"); var per2 = per with {Name="Duru"}; |
Böylece geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.
Source: https://devblogs.microsoft.com/dotnet/whats-new-in-csharp-7-0/
Source Code : https://github.com/borakasmer/C-7.0-Futures
Son Yorumlar