İlkay İlknur

just a developer...

C# 7.0 - Tuples

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

C# 7.0 ile beraber gelecek olan önemli özelliklerden biri de Tuple'lar. Tuple tiplerine aslında çokta yabancı değiliz. Tuple tipiyle ilk olarak .NET Framework 4.0 ile tanışmıştık. Hani şu içerisinde Item1, Item2, Item3 diye propertyler olan tipler :) Çoğu zaman aslında kullanmak istediğimiz ama bu property isimlerinden dolayı kullanma konusunda içimizin rahat olmadığı tipler :)

Tupleların en önemli kullanım alanları aslında bir metottan birden fazla değer döndürmek zorunda kaldığımız durumlar. C# içerisinde aslında bir metottan birden fazla değer döndürmek istediğimizde out parametrelerini kullanabiliyoruz.

private void Foo(int param1, out int intReturnParam, out string stringReturnParam)
{

}

Ancak out parametreler maalesef async metotlarda kullanılamıyor. Dolayısıyla bu durumda Tuple tipini kullanmak durumunda kalıyoruz.

private async Task<Tuple<intstring>> FooAsync(int param1)
{

}

private async void Barrier()
{
    var result = await FooAsync(1);
    Debug.WriteLine($"{result.Item1} : {result.Item2}");
}

Bu durumda da metodu çağıran veya kullanan yazılımcılar aslında bu async metottan ne döndüğü konusunda hiçbir şekilde bilgi sahibi olamıyorlar. Item1, Item2 fieldlarını ne işe yaradığını, hangisinde hangi bilgi olduğunu iyi bir şekilde dökümante etmeniz gerekiyor. Ayrıca mevcut Tuple tipi bir class olduğu için heap allocationa neden oluyor.

Tüm bu nedenlerden dolayı aslında gerçek anlamda Tuple desteği C# 7.0 ile beraber geliyor. Peki C# 7.0'da Tuple'lar nasıl olacak. Gelelim bu kısma.

Metotlarda birden fazla değer döndürmek istediğimizde döndüreceğimiz alanların tiplerini ve isimlerini parantez içerisinde yazmamız gerekecek.

static (int count, string value) Foo()
{

}

static Task<(int count, string value)> FooAsync()
{

}

Yukarıda gördüğünüz gibi Foo metodunun dönüş değeri bir tuple ve bu tuple'ın içerisinde count ve value diye 2 tane alan bulunuyor. Ayrıca Task döndüren asenkron metotların da dönüş tipleri gördüğünüz gibi tuple olabiliyor. Bu şekilde tuple dönüş tiplerini tanımladıktan sonra peki metot içerisinde bir tuple nasıl tanımlıyoruz kısmına bakalım. Tanımlama için birden fazla kullanım senaryosu var aslında. İlk olarak normal bir object yaratırmış gibi tuple yaratma.

static (int count, string value) Foo()
{
    var retVal = new(int count, string value)
    {
        count = 1,
        value = "Bar"
    };

    return retVal;
}

Gördüğünüz gibi aslında oldukça basit. Anonymous object tanımlar gibi tanımlıyoruz, sadece ek olarak tuple içerisinde bulunacak olan alanların isimlerini ve tiplerini parantez içerisinde yazıyoruz. Ancak bu kullanım geçerli olsa da kullanım olarak çok da kolay değil. Bunun yerine C# 7.0 ile beraber daha özel bir tanımlama syntax'ı geliyor.

static(int count, string value) Foo()
{
    var retVal = (count: 1, value: "Foo");
    return retVal;
}

Parantez içerisinde sadece alanın adını ve değerini yazdığınızda da compiler arka planda aynı anonymous objectlerde olduğu gibi alanın tipini kendisi buluyor ve ona uygun tuple tipini yaratıyor. Ayrıca yine tipin compiler tarafından bilindiği durumlarda da tuple'lardaki field adlarının pekte önemi olmuyor. Compiler arka planda ilgili çevrimi kendisi yapıyor.

static (int count, string value) Foo()
{
    var retVal = (c: 1, v: "Foo");
    return retVal;
}

Tuple Deconstruction

Bir metottan veya herhangi bir yerden bir tuple döndüğünde o tuple içerisindeki değerleri ayrıştırmak ve metodun devamında ayrıştırılmış halini kullanmak önemli. Bu yüzden tuple içerisindeki alanları ayrıştırıp içerisindeki değerleri değişkenlere atamak için de kolay bir syntax geliyor C# 7.0 ile.

static void Main(string[] args)
{
    (var count, var value) = Foo();
}

static (int count, string value) Foo()
{
    var retVal = (c: 1, v: "Foo");
    return retVal;
}

Main metodunda göründüğü gibi Foo metodundan dönen tuple tipi içerisindeki alanları count ve value ismindeki local değişkenlere atamasını yapabiliyoruz. Böylece aslında tuple tipleri tamamen görünmez bir şekilde kalabiliyorlar. Yani siz bir metottan tuple döndüğünü biliyorsanız, bu tuple içerisindeki alanları hemen hızlıca lokal değişkenlere alıp kodunuzu temiz tutabilirsiniz.

C# 7.0 ile beraber gelen tuple'ların Framework içerisinde bulanan Tuple'lardan bazı farkları var. Bunlardan ilki C# 7.0 tuple'larının struct olması. Böylece bu tupleların yaratılmaları daha az maliyetli. Ayrıca C# 7.0 tuple'ları mutable. Yani bir tuple yarattıktan sonra fieldın değerini değiştirebilirsiniz. Ancak .NET Framework içerisindeki Tuple tipleri immutable. Yani yarattıktan sonra fieldın değerini sadece okuyabilirsiniz, değiştiremezsiniz.

Son olarak Tuple tiplerini denemek isterseniz test için Visual Studio Preview 15 kullanmanız gerekiyor. Eğer test yaparken tuple kullanımından sonra derlerken aşağıdaki hatayı alırsanız nuget üzerinden "System.ValueTuple" prerelease paketini yüklemeniz gerekiyor. Bu şimdilik bir gereklilik ancak ürün release olduğunda buradaki tipler BCL'e eklenecektir.

Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference ?

Bir sonraki yazıda görüşmek üzere...

Not : Yukarıdaki örnekler Visual Studio 15 Preview 4 ile yazılmış ve test edilmiştir.



BenchmarkDotNet ile Performans ve Memory Benchmarking

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Bir ürün geliştirirken ne kadar dikkat ediyoruz bilmiyorum ama geliştirdiğimiz uygulamanın en önemli özelliklerinden biri de hiç kuşkusuz ki uygulamanın performansı. Kimi zaman "abi önce çalışsın, sonra performansa bakarız" dedikten sonra ne yazık ki o "sonra" hiçbir zaman gelmiyor taa ki müşteriden bir şikayet alana yada out of memory exception gelene kadar :D

Bu yazıda sizlere benim de arada kullandığım bir benchmarking aracı olan DotNetBenchmark'tan bahsedeceğim. Yukarıda bahsettiğim gibi müşteriden bir şikayet veya exceptionlar almadığımız sürece bu performans veya memory kullanımı olaylarına pek bakmayız. Ama bunlar geldiği zaman da kodların aralarına Stopwatch'lar koyarak süreleri veya memory'i ölçmeye çalışırız. Bu sırada yazdığımız kod da kirlenir vs.. sonra bir de bu ölçüm yaptığımız kodları toparlamak gerekir, zorlanırız. Ayrıca da ölçüm için doğru yöntemleri kullandığımızdan emin olmamız gerekiyor. BenchmarkDotNet aracı işte tüm bu pis işleri de kendisi doğru bir şekilde halletiği için de oldukça güzel bir tool. Şimdi gelelim bu toolu nasıl kullanacağımıza.

İlk olarak BenchmarkDotNet librarysini aşağıdaki komutla Nuget paketi olarak projenize ekleyebilirsiniz.

PS> Install-Package BenchmarkDotNet 

Projenize paketi ekledikten sonra artık herşey oldukça basit. Şimdi diyelim ki bir liste üzerinde LINQ sorgusu ile normal for döngüsünü karşılaştırmak istiyorsunuz. Aşağıdaki gibi basit bir class içerisinde aynı sorguyu hem LINQ ile hem de for döngüsü ile yazıyoruz. Daha sonra yapmamız gereken şey ise metotları Benchmark attribute'ü ile işaretlemek.

public class LINQvsFor
{
    private List<string> list = Enumerable.Range(1, 2000).Select(t => t + "name").ToList();

    [Benchmark]
    public List<string> For()
    {
        List<string> retVal = new List<string>();
        for (int i = 0; i < list.Count; i++)
        {
            if (list[i].Contains("1"))
            {
                retVal.Add(list[i]);
            }
        }
        return retVal;
    }
    [Benchmark]
    public List<string> LINQ()
    {
        return list.Where(t => t.Contains("1")).ToList();
    }
}

Daha sonra BenchmarkRunner sınıfını kullanarak bir console app üzerinde bu testi çalıştırıp sonucunu hızlı bir şekilde görebiliriz. Tabi sonuçları en doğru şekilde alabilmek için testi Release modda çalıştırmayı unutmamak gerekiyor :)

class Program
{
    static void Main(string[] args)
    {
        BenchmarkRunner.Run<LINQvsFor>();
    }
}

Benchmark testlerini çalıştırdıktan sonra çıktıları pek çok farklı formatta(Markdown,CSV) vs.. alabilmemiz mümkün. Bunun için basit bir config sınıfı yazıp benchmarkı çalıştırırken configi parametre olarak geçmemiz gerekiyor. Örneğin Markdown olarak export almak istersek...

class Program
{
    static void Main(string[] args)
    {
        BenchmarkRunner.Run<LINQvsFor>();
    }
}

public class Config : ManualConfig
{
    public Config()
    {
        Add(MarkdownExporter.Default);
    }
}

Benchmark testlerimizi belirli parametre kombinasyonlarında da çalıştırmamız mümkün. Bunun için ilgili fieldı Params attribute'ü ile işaretleyip alacağı değerleri belirtmemiz yeterli.

Örneğin,

public class StringConcatTest
{
    [Params(1, 2, 3, 4, 5, 10, 100, 1000)]
    public int loops;

    [Benchmark]
    public string StringConcat()
    {
        string result = string.Empty;
        for (int i = 0; i < loops; ++i)
            result = string.Concat(result, i.ToString());
        return result;
    }

    [Benchmark]
    public string StringBuilder()
    {
        StringBuilder sb = new StringBuilder(string.Empty);
        for (int i = 0; i < loops; ++i)
            sb.Append(i.ToString());
        return sb.ToString();
    }
}

Yukarıdaki testler Params attribute'ünde belirttiğimiz parametreler için teker çalıştırılacak. Sonuçlarını da belirtilen her parametre için ayrı ayrı alacağız.

Kodunuzun ne kadar memory kullandığı ile ilgili analiz yapmak isterseniz de öncelikli olarak bir ek nuget paketini daha projenize eklemeniz gerekiyor.

PS> Install-Package BenchmarkDotNet.Diagnostics.Windows 

Bu paketi de ekledikten sonra aşağıdaki gibi MemoryDiagnoser ekleyerek memory kullanımı ile ilgili sonuçları da elde edebiliriz.

class Program
{
    static void Main(string[] args)
    {
        var config = new ManualConfig();
        config.Add(DefaultConfig.Instance);
        config.Add(new MemoryDiagnoser());

        BenchmarkRunner.Run<StringConcatTest>(config);
    }
}

Uygulamayı çalıştırdığımızda...

Gördüğünüz gibi BenchmarkDotNet toolu oldukça kuvvetli bir tool. Bu yazıda bahsedemeyeceğim pek çok farklı özelliği de ayrıca içerisinde barındırmakta. Örneğin testlerini belirli ortamlar için çalıştırabiliyorsunuz. Bir testi base olarak alıp diğer testlerin sonuçlarını ona göre karşılatırabilmeniz de mümkün. Projenin temel amacı benchmarkingi kolay ve güvenilir olarak yapmak olduğu için aslında oldukça complex testleri hızlı bir şekilde 1-2 ufak değişiklikle yapabiliyorsunuz. Bu nedenle testlere başlamadan önce projenin readme sayfasını okumanızı tavsiye ederim.

Projenin Github reposunda ek olarak pekçok örnek benchmark testleri de bulunmakta. Yukarıda kullandığım string concat testi de dahil olmak üzere bu testler için de https://github.com/PerfDotNet/BenchmarkDotNet/tree/stable/BenchmarkDotNet.Samples klasörüne bakabilirsiniz.

Benchmark olayı kritik bir konu olduğu için projenin kullanıldığı yerlerin referanslarına da https://github.com/PerfDotNet/BenchmarkDotNet/wiki/People-using-BenchmarkDotNet adresinden ulaşabilirsiniz. Proje ile ilgili daha detaylı bilgiye de projenin contributerlarından olan Matt Warren'ın blogundan erişebilirsiniz.



C# 7.0 - Pattern Matching

Şu ana kadar C# 7.0 ile beraber gelmesi planlanan pek çok özelliği inceledik. Bu blog postu da saymazsak incelemediğimiz sadece 3 özellik kalıyor. BU özellikler pattern matching, out var ve tuples.

Bu blog postta ise pattern matching özelliğine bakacağız. C# 7.0 ile beraber gelecek en büyük özelliklerden biri olan pattern matching ile ilgili çektiğim videoyu aşağıdan izleyebilirsiniz.

Video Linki : https://www.youtube.com/watch?v=HzSh0PFBfoQ

Pattern Matching Kod Örnekleri: https://github.com/ilkayilknur/csharp-7-new-features/tree/master/PatternMatching

Görüşmek Üzere



C# 7.0 Kod Örnekleri

C# 6.0 zamanlarında özellikleri anlatan kod örneklerini Github üzerinden paylaşmıştım. C# 7.0 versiyonu da artık yavaş yavaş belirginleşmeye ve release olmaya doğru giderken benzer tarzda örnekleri C# 7.0 içinde koymaya karar verdim.

İlgili örneklere https://github.com/ilkayilknur/csharp-7-new-features adresinden ulaşabilirsiniz. Hatta ekleyebileceğiniz özel kullanım durumları da varsa pull request gönderebilirsiniz.

Görüşmek Üzere



C# 7.0 - Digit Separators

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Not : Bu makaledeki örnekleri denemek için gereken ortam kurulum bilgisini buradan alabilirsiniz.

C# 7.0 ile beraber gelmesi planlanan ufak özelliklerden biri de digit separatorler. Digit separatorler ile numeric değer tanımlamaları sırasında istediğiniz bölümde basamakları ayırabiliyorsunuz. Böylece kod yazarken tanımlamış olduğunuz numeric değişkenlerin taşıdıkları değerler daha okunabilir olurken hem de siz tanımlama esnasında basamakları ayırabildiğiniz için hata yapma olasılığınız daha düşük oluyor. Digit separator olarak ise _ kullanıyoruz.

Örneğin,

int x = 1_000_000;
double y = 1_00.0_9;

Digit separatorlerin bir diğer kullanım alanı da binary literal'lar. Binary literal tanımlamaları esnasında da digit separatorleri kullanmamız mümkün.

Örneğin,

int x = 0b11_00_0_01;
double y = 0b1_00;

Bu ufak özellikle ilgili yazımızda bu kadar. Bir sonraki C# 7.0 özelliğinde görüşmek üzere...



C# 7.0 - Binary Literals

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Not : Bu makaledeki örnekleri denemek için gereken ortam kurulum bilgisini buradan alabilirsiniz.

C# 7.0 ile beraber gelmesi muhtemel özelliklerden biride Binary Literals özelliği. Aslında C# design meetinglerini takip edenler için bu özellik süpriz bir özellik değil. Çünkü aslında aynı özellik C# 6.0'da da planlanıyordu ancak release döneminde bu özellik ne yazık ki C# 6.0'a dahil edilmedi.

İşin magazin tarafını bir kenara bırakırsak :) binary literals ile kod içerisinde binary olarak tanımlamalar yapabiliyorsunuz. Bunu yapmak için binary ifadenin başına 0b veya 0B yazmanız yeterli.

Örneğin,

static void Main(string[] args)
{
    int x = 0b1100001;
    double y = 0b100;
}

Gördüğünüz gibi kullanımı oldukça basit. Gelelim bu özellik nerelerde işimize yarayacak kısmına. Enumlara Flags attribute'ünü ekleyip 2'nin üssü bir biçimde değerler verdiğimizde enumlar üzerinde bitwise operasyonlar yapabiliyoruz. (Enumlar üzerinde bitwise operasyonlar ile ilgili yazmış olduğum yazıyı inceleyebilirsiniz. http://www.ilkayilknur.com/coklu-enum-degerleriyle-calismak) Burada 2'nin üssü değerleri verirken binary literalleri kullanabiliriz. Böylece hızlı bir şekilde ve daha az hata olasılığıyla hızlı bir şekilde kodumuzu yazabiliriz.

[Flags]
enum Colors
{
    Red = 0b1,
    Green = 0b10,
    Blue = 0b100
}

Gördüğünüz gibi binary literallerin bana göre en önemli kullanım alanı burası olacak. Bunun yanında C# ekibi binary ifadeleri öğrenen developerların da C# içerisinde eğitim amaçlı binary literalleri kullanacaklarını düşünüyorlar.

C# 7.0 binary literals özelliğiyle ilgili yazımız bu kadar. Zaten gördüğünüz gibi oldukça ufak bir özellik :) Bir sonraki yazıda görüşmek üzere...



C# 7.0 - Local Functions

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Not : Bu makaledeki örnekleri denemek için gereken ortam kurulum bilgisini buradan alabilirsiniz.

C# 7.0 ile beraber gelmesi muhtemel en basit özelliklerden biride local functions özelliği. Hemen örnek yapmadan önce ilk olarak bu özelliğe ne gerek vardı sorusunun cevabını vermeye çalışalım.

Kod yazarken metotların çok fazla uzadığı ve bakımının zorlaştığı senaryolarda metot içerisindeki fonksiyonel bölümleri ayrı bir metot yaparız ve ilgili metot içerisinden de dışarıya aldığımız diğer metodu çağırırız. Bu ufak helper metotlarımız aslında baktığımızda sadece tek bir metot tarafından kullanılırlar ancak tanımlandıkları class'ın bir üyesi olurlar. Dolayısıyla bu helper metotları private olarak tanımlasak bile herhangi bir developer class içerisindeki başka bir metot içerisinden de istemememize rağmen bu metodu çağırabilir.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        //Do something
        HelperMethod();
    }

    private void HelperMethod()
    {

    }
}

Örneğin yukarıdaki kodda HelperMethod isimli metot aynı class içerisindeki başka bir metottan da çağırılabilir.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        //Do something
        HelperMethod();
    }

    private void HelperMethod()
    {

    }

    void Bar2()
    {
        HelperMethod();
    }
}

Bu aslında istenmeyen birşey olsa da bunun önüne geçmek pek mümkün değil. Tek kaçış yolu lambda ifadesi kullanarak Func veya Action tipinde bu helper metotları tanımlamak.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        Action helper = () => { };
        //Do something
        helper();
    }
}

Bu durumda helper kısmı lambda ifadasi ile tanımladığımız için bu lambda ifadesi sadece Bar metodu içerisinden çağırılabilir ve erişilebilir. Böylece aslında en baştan amaçladığımız şeyi gerçekleştirmiş oluruz. Ancak Action ve Func olarak tanımlamanın bazı kısıtlamaları ile performans ve memory bakımından da bazı dezavantajları var.

Sahip oldukları kısıtlamalardan bazıları

  • Lambda ifadeleri generic olarak tanımlanamaz.
  • Lambda ifadeleri içerisinde ref, params ve out olarak parametre tanımlayamayız.
  • Lambda ifadelerini recursive olarak çağırmak için ufak bir trick yapmak gerekiyor. Tanımlama esnasında kendisini çağıramaz.

Tüm bu sıkıntılardan ötürü C# 7.0'da local functions özelliğinin getirilmesi planlanıyor. Şimdi gelelim local functions özelliğinin kullanımına.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        void HelperMethod()
        {

        }

        HelperMethod();
    }
}

Yukarıda da gördüğünüz gibi metot içerisinde yeni bir metot tanımlamaktan başka birşey yapmıyoruz aslında. Dolayısıyla out, ref ve params parametrelerini de kullanabiliyoruz. Ayrıca bu metotların çağırımında da herhangi bir ekstra performans kaybı veya ekstra memory kullanımı da olmuyor. Local functionlar sadece tanımlı bulundukları metot içerisinden erişilebilir durumdalar. Yani başka bir metot içerisinden local function'ın çağırılması gibi bir durum söz konusu da değil. Yukarıdaki kodda da gördüğünüz gibi bir local functionı çağırmadan önce yukarıda o local function'ı tanımlamış olmak gerekiyor. Ayrıca local functionda, içerisinde bulunduğu metot içerisindeki her elemana da ulaşabilirsiniz.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        void HelperMethod()
        {
            foreach (var item in list)
            {

            }
        }

        HelperMethod();
    }
}

C# 6.0 ve C# 7.0 Birarada

Yazıyı sonlandırmadan önce C# 6.0'da gelen expression-bodied function members özelliğini kullanarak local functions tanımlamadan bahsetmek istiyorum. Böylece tek satırlık bir local functionınız olduğunda hızlı bir şekilde bu özelliği kullanarak local functions tanımlayabilirsiniz.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        void HelperMethod() => Console.WriteLine("Hello");

        HelperMethod();
    }
}

Evet, local functionsla ilgili bu yazıda bahsedeceklerimiz bu kadar. Gördüğünüz gibi ufak ama faydalı bir özellik gibi duruyor. Tabi C# developerların bu özelliği ne kadar benimseyeceklerini de merak etmiyor değilim.

Bir sonraki yazıda görüşmek üzere...



C# 7.0 Özelliklerini Nasıl Test Ederiz ?

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Bir önceki blog yazısında C# 7.0 yeniliklerinden bahsettiğim videomu paylaşmıştım. Diyelim ki videoyu izlediniz veya başka yerlerden okuyup heyecanlandınız ve C# 7.0 özelliklerini test etmek istiyorsunuz :) Bu özellikleri test edebilmeniz için önünüzde 2 yol var. Biri kısmen kolay olan yol diğeri ise oldukça zorlu :) Önce kolay olandan başlayalım.

Visual Studio 15 Preview Üzerinde Test Etmek

Şu anda C# 7.0 özelliklerini test etmenin en kolay yolu Visual Studio 15 Preview kullanmak. Visual Studio 15 Preview sürümü adı üzerinde henüz preview olduğu için production makinanıza kurmanızı kesinlikle tavsiye etmiyorum. Bu yüzden bilgisayarınızda bir sanal makina yaratıp orada Visual Studio 15'i kurup testlerinizi yapabilirsiniz. Bir diğer alternatif ise Azure üzerinde Visual Studio 15 Preview imajlı bir VM yaratmak.

Visual Studio 15 Preview Installer Linki : http://aka.ms/vsnext

Visual Studio 15 Preview'ı kurdunuz ve hemen bir proje yaratıp özellikleri test etmek istiyorsunuz. Bir örnek yaptınız ama o da ne projeniz derlenmiyor ve hata veriyor.

Bu hatayı almamızın sebebi C# 7.0 özelliklerinin her birinin feature flagleri arkasına alınması. Yani ekip hızlı bir şekilde istediği özellikleri açıp kapatabiliyor gerekli olduğunda. Bu hatayı aşmanın yolu ise oldukça basit. Test yaptığımız projeye conditional compilation symbols olarak __DEMO__ ve __DEMO_EXPERIMENTAL__ 'ı eklemek.

Bu işlemi de yaptıktan sonra kodunuz başarılı olarak derlenecektir. Ancak her Visual Studio 15 Preview versiyonunda, duyurulan C# 7.0 özellikleri olmayabilir. Örneğin bu yazının yazıldığı dönemde bulunan Visual Studio 15 Preview içerisinde Tuple özellikleri henüz bulunmuyor.

Roslyn Source Code'unu Çalıştırıp Test Etmek

Gelelim diğer opsiyona. Github üzerinden Roslyn projesinin kodlarını indirip projeyi derleyip aynı şekilde özellikleri test edebilirsiniz. Daha önce bunu denemiş biri olarak uyarmam gerekir ki bu iş göründüğü kadar kolay değil. Kısaca yol göstermem gerekirse

Şimdiden bu opsiyonla uğraşacaklara kolaylıklar diliyorum :) Daha öncede bahsettiğim gibi en kolay opsiyon Visual Studio 15 Preview üzerinden testleri yapmak.

Bir sonraki yazıda görüşmek üzere.



C# 7.0'da Bizi Neler Bekliyor ?

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

C# 7.0'da Bizi Neler Bekliyor ?

C# 7.0 ile ilgili planlamalar daha C# 6.0 release olmadan önce başlasada bazı şeyler tam oturmadan herhangi bir paylaşımda bulunmak istememiştim. Artık Build konferansıyla beraber yavaş yavaş ana temaların belirginleşmesinden sonra C# 7.0 yazılarına başlamadan önce durumu özetleyen ve özelliklere kısaca değindiğim bir video çektim. Eğer C# 7.0 ile beraber neler gelecek diye merak ediyorsanız aşağıdaki videoyu izleyip bilgi sahibi olabilirsiniz.



Video Linki : https://www.youtube.com/watch?v=JPPWPtwXMFA



Visual Studio 2015 Update 2 İle Gelen Yenilikler

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Build 2016'nın en önemli duyurularından biri de Visual Studio 2015 Update 2'nin release olmasıydı. Update 2 içerisinden bolca bug fix barındırsada bahsetmeye değer bazı yeni özellikler de barındırmakta.

Universal Platform Yenilikleri

Update 2 ile beraber Universal App'lerde kullandığımız Microsoft.NETCore.UniversalWindowsPlatform nuget paketininde 5.1.0 versiyonu release oldu. Visual Studio 2015 Update 2'yi yüklediğinizde bu nuget paketini update etmenizde fayda var.

Update 2 ile beraber gelen bir diğer özellik ise Universal App yaratma aşamasında karşımıza çıkan version seçim ekranı. Bu ekran ile uygulamanızın target edeceği ve minimum olarak destekleyeceği Windows 10 versiyonunu uygulama yaratırken seçebiliyorsunuz.

Update 2 ile beraber gelen en beğendiğim özellik ise basit ama zaman kazandıran bir özellik. Daha önceden Universal App'inizi store'a göndermek için paket yaratmak istediğinizde her seferinde live accountunuzla login olmak zorunda kalıyordunuz. Ancak Update 2 ile beraber bu sorunu çözmüşler ve Store'a bir kere login olduğunuzda Visual Studio artık bu account bilgilerini otomatik olarak hatırlıyor.

Interactive Window Yenilikleri

Visual Studio 2015 Update 1 ile beraber gelen en önemli yeniliklerden biri de Interactive Window'du. (Eğer daha önce Interactive Window'u duymadıysanız yazmış olduğum yazıyı okuyabilirsiniz.) Update 2 ile beraber Interactive Window tarafında da yenilikler mevcut. Bu yenilikler çalışmış olduğunuz proje içerisindeki kodları hızlı bir şekilde Interactive Window üzerinden çalıştırmanıza olanak sağlıyor. Bunun için Visual Studio içerisinde çalıştırmak istediğiniz kodu seçip sağ tıklayıp "Execute in Interactive"'i tıklamanız yeterli.

Editör Yenilikleri

Update 2 içerisinde güzel editör yenilikleri de bulunmakta. Bunlardan ilki using/import eklerken artık fuzzy matching yapılması. Yani eğer bir tipin adını yanlış yazarsanız Visual Studio tipin adından tahminde bulunuyor ve size uygun öneriyi sunup hem tipin adını düzeltiyor hem de ilgili using/import'u ekliyor.

Update 2 içerisinde ayrıca yeni refactoringler de bulunuyor. Bunlardan ilki delegate işletimlerinde null propagator operatörü kullanımını öneren refactoring.

Diğer refactoring ise make method synchronous refactoringi.

Bu yazıda değinmek istediğim yenilikler bunlar. Update 2 ile beraber gelen tüm yenilikleri https://www.visualstudio.com/en-us/news/vs2015-update2-vs.aspx adresinde bulabilirsiniz.