C# 7 Tuple Kullanımı

Klasik Kullanım

var point = new Tuple<int, int>(0, 1);
var x = point.Item1;

Pratik Yazım

var point = (0, 1);
var x = point.Item1;

Tuple üzerindeki değerleri isimlendirme

var point = (X: 0, Y: 1);
var x = point.X;

Değer isimlerinin değişkenden alınması

var X = 0;
var Y = 1;
var point = (X, Y);
var x = point.X;

Metot geri dönüş tipi olarak.

Anonim tiplerin geri dönüş değeri olarak kullanılamaması dolayısıyla, anonim tipler için büyük bir alternatif.

Değerlere ad verebildiğimiz için, basit DTO'lar için, ayrı bir DTO yazmak yerine doğrudan Tuple kullanımını da mümkün kılıyor.

class MyClass
{
    (int X, int Y) GetPoint()
    {
        return (0, 1);
    }
}

var point = new MyClass().GetPoint();
var x = point.X;
Etiketler:  C#

Compress & Decompress String in C#

Compress and decompress string in C#.

Usage

var str = "String to be compressed";
var strCompressed = Cipher.Compress(str);
var strDecompressed = Cipher.Decompress(strCompressed);

Cipher class

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

public static class Cipher
{
    /// <summary>
    /// String compress
    /// </summary>
    public static string Compress(string uncompressedString)
    {
        if (String.IsNullOrEmpty(uncompressedString))
        {
            return uncompressedString;
        }

        using (var compressedStream = new MemoryStream())
        {
            using (var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(uncompressedString)))
            {
                using (var compressorStream = new DeflateStream(compressedStream, CompressionMode.Compress, true))
                {
                    uncompressedStream.CopyTo(compressorStream);
                }

                return Convert.ToBase64String(compressedStream.ToArray());
            }
        }
    }

    /// <summary>
    /// String decompress
    /// </summary>
    public static string Decompress(string compressedString)
    {
        if (String.IsNullOrEmpty(compressedString))
        {
            return compressedString;
        }

        using (var decompressedStream = new MemoryStream())
        {
            using (var compressedStream = new MemoryStream(Convert.FromBase64String(compressedString)))
            {
                using (var decompressorStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
                {
                    decompressorStream.CopyTo(decompressedStream);
                }

                return Encoding.UTF8.GetString(decompressedStream.ToArray());
            }
        }
    }
}
Etiketler:  C#

Mersenne Asalları

Mersenne sayıları, ikinin kuvvetlerinin bir eksiği şeklinde olan sayılardır. n doğal sayısı için Mn = 2n - 1 şeklinde hesaplanır.

Mersenne asal sayıları, hem bir Mersenne sayısı hem de asal olan sayılardır. n sayısı için Mn = 2n - 1 işleminin sonucu bir asal sayı ise bu sayıya Mersenne asal sayısı denir.

Mersenne asal sayılarına örnek olarak,

n = 2 için 22 - 1 = 3
n = 3 için 23 - 1 = 7
n = 5 için 25 - 1 = 31

verilebilir. 3, 7 ve 31 asal sayılardır.

Günümüzde bulunan en büyük asal sayılar, Mersenne asallarından oluşmaktadır. Mersenne asallarının tespit edilmesinde kullanılan bazı pratik yöntemlerden dolayı, yeni asal sayı araştırması yapan gruplar, Mersenne asalları üzerine yoğunlaşmıştır.

2016 'nın Ocak ayı itibariyle 49 Mersenne asal sayısı bilinmektedir. Bilinen en büyük Mersenne asal sayısı 274.207.281 - 1'dir.

Teorem

Bir Mersenne sayısının asal olabilmesi için, ikinin kuvvetinin de asal olması gerekir.

Geometrik seriler için,

s = 1 + r + r2 + r3 + ... + rn-1

Eşitliğin her iki tarafını r ile çarparsak,

rs = r + r2 + r3 + r4 + ... + rn

İki eşitliğin farkı,

s - rs = 1 - rn
s(1 - r) = 1 - rn
rn -1 = s(r - 1)

Teoreme göre, ikinin kuvveti asal değilse, Mersenne sayısının da asal olmaması gerekir. İkinin kuvveti, yani n değeri asal değilse, n değeri axb şeklinde, iki tam sayının çarpımı şeklinde yazılabilir.

2ab değerini 2ab şeklinde yazarsak, 2ab - 1 = s(2a - 1) olur.
2ab değerini 2ba şeklinde yazarsak, 2ba - 1 = s(2b - 1) olur.

Yukarıdaki iki eşitliğe göre, 2ab - 1 değeri hem 2a - 1 hem de 2b - 1 değerine tam olarak bölünür. Yani bu durumda, birden fazla böleni olduğu için 2ab - 1 değeri asal olmaz.

Lucas-Lehmer Asallık Testi

Bir Mersenne sayısının asal olup olmadığını anlamak için kullanılan etkili bir yöntemdir. Klasik yöntemlere göre, bir Mersenne sayısının asal olup olmadığını tespit etmek için gerekli süre, bu test ile dramatik bir şekilde kısalmaktadır.

Lucas-Lehmer asallık testine göre, 2p - 1 sayısının asal olması için aşağıdaki şartın sağlanması gereklidir.

S(0) = 4
S(n) = (S(n-1)2 - 2) mod (2p-1)

rekürsif fonksiyona göre

S(p-2) = 0

değerini veriyorsa, 2p - 1 Mersenne sayısı asaldır.

Örnek vermek gerekirse, 27 - 1 sayısını asal olup olmadığına bakalım. Bu sayının asal olması için, S(p - 2) yani S(5) değerinin 0 olması gerekir.

S(0) = 4 
S(1) = (4x4 - 2) mod 127 = 14 
S(2) = (14x14 - 2) mod 127 = 67 
S(3) = (67x67 - 2) mod 127 = 42 
S(4) = (42x42 - 2) mod 127 = 111 
S(5) = (111x111 - 2) mod 127 = 0

Dolayısıyla, 27 - 1 sayısı asaldır.

Lucas-Lehmer testinin C# dilinde yazılmış kaynak kodu yer almaktadır.

using System;
using System.Numerics;

namespace SG.Algorithm
{
    public class MersenneNumber
    {
        /// <summary>
        /// (2^p - 1) değerinin asal sayı olup olmadığına bakılıyor.
        /// </summary>
        public bool IsPrimeNumber(int p)
        {
            if (p < 2)
            {
                throw new ArgumentException(nameof(p));
            }

            // Eğer p değeri çift ise, sadece 2 değeri için Mersenne asalı olur.
            if (p % 2 == 0)
            {
                return p == 2;
            }

            // (2^p - 1) sayısının asal olması için, p değerinin de asal olması gerekiyor.
            // Tüm tek sayılara göre mod alma işlemi uygulanarak, p sayısının asal olup olmadığına bakılıyor.
            // Döngünün p^(1/2) ye kadar çalışması yeterli. Hiçbir sayı, karekök değerinden büyük bir sayıya tam olarak bölünemez.
            for (int i = 3; i <= (int)Math.Sqrt(p); i += 2)
            {
                if (p % i == 0)
                {
                    // Tam olarak bölünüyor, asal değil.
                    return false;
                }
            }

            // Değer çok büyük olabileceği için BigInteger kullanılmıştır.
            var mode = BigInteger.Pow(2, p) - 1;

            // S fonksiyonu başlangıç değeri
            var S = new BigInteger(4);

            // S(p-2) değeri bulunacak
            for (int n = 1; n <= p - 2; n++)
            {
                // S(n) = (S(n-1)^2 - 2) mod (2p-1)
                S = (BigInteger.Pow(S, 2) - 2) % mode;
            }

            // S(p-2) değeri 0 ise, (2^p - 1) değeri asaldır.
            return S == 0;
        }
    }
}
Etiketler:  C#

Newton-Raphson Metodu ile Fonksiyon Kök Bulma

Newton-Raphson metodu, sayısal analizde, eşitlik köklerinin bulunmasında en yaygın kullanılan metotlardan birisidir. Başlangıç için tahmini bir kök değeri seçilerek, yapılan iterasyon sonucu gerçek kök değerine oldukça yakın bir değere ulaşılır.

Newton-Raphson

Newton-Raphson metodunun C# dilinde yazılmış kaynak kodu yer almaktadır.

public class NewtonRaphson
{
    public uint MaxIteration { get; set; } = 50;
    public double Epsilon { get; set; } = 0.000001;

    public double Solve(Func<double, double> f, Func<double, double> df, double initialGuess)
    {
        var xn = initialGuess;

        for (var i = 0; i < this.MaxIteration; i++)
        {
            var xn1 = xn - f.Invoke(xn) / df.Invoke(xn);

            if (Math.Abs(xn - xn1) < this.Epsilon)
            {
                return xn1;
            }

            xn = xn1;
        }

        return xn;
    }
}

Örneğin f(x) = x^2 - 2 fonksiyonun köklerini bulmak için, metodu aşağıdaki şekilde çağırabiliriz. Tahmini kök değeri olarak 1 seçilmiştir.

var solver = new NewtonRaphson();
var root = solver.Solve(x => x * x - 2, x => 2 * x, 1);

Benzer şekilde, f(x) = x - Cos(x) fonksiyonun köklerini bulmak için ise, metodu aşağıdaki şekilde çağırabiliriz. f(x) = 1 + Sin(x) fonksiyonun türevidir.

var solver = new NewtonRaphson();
var root = solver.Solve(x => x - Math.Cos(x), x => 1 + Math.Sin(x), 2);
Etiketler:  C#

C# 6.0 Exception Filter

tip

try catch kullanımı sırasında, catch bloğunun çalışması için koşul yazılabilir.

Örnek

try
{
    // Code
}
catch (ArgumentException ex) when (ex.ParamName == "p1")
{
    // ex.ParamName == "p1" koşulu sağlanması durumunda catch bloğu çalışır.
}
Etiketler:  C#

LINQ Cheat Sheet

LINQ kod içerisinde SQL tarzı sorgular yapabilmemize olanak sağlayan bir teknolojidir.

lambda

Urun nesnelerinin ve tamsayı değerlerinin yer aldığı iki farklı dizi üzerinde sorgulama işlemleri gerçekleştirilecektir.

        public class Urun
        {
            public int Numara { get; set; }
            public string Ad { get; set; }
            public string Kategori { get; set; }
            public double Deger { get; set; }
        }

        var dizi = new[] { 2, 3, 7, 4, 5, 4, 9, 1, 3 };
        var urunler = new[]
        {
            new Urun { Numara = 1, Ad = "Kalem", Kategori = "Kırtasiye", Deger = 3 },
            new Urun { Numara = 2, Ad = "Elma", Kategori = "Manav", Deger = 4.2 }
        };

Süzme (Filter)

        // Değeri 3 olan dizi elemanları alınıyor
        var sonuc = (from c in dizi
                        where c == 3
                        select c);

        // 2 farklı kritere göre süzme
        var sonuc = (from c in urunler
                        where c.Kategori == "Manav" && c.Deger > 1
                        select c);

        // Lambda Syntax
        var sonuc = urunler.Where(c => c.Ad == "Elma");

Yansıtma (Projection)

        // Ürünlerin sadece belirli özellikleri listeleniyor.
        // Anonim tip geri döndürülüyor.
        var sonuc = (from c in urunler
                        select new
                        {
                            c.Numara,
                            c.Ad
                        });

        // Lambda Syntax
        var sonuc = urunler.Select(c => new
        {
            c.Numara,
            c.Ad
        });

Sıralama (Order)

        // Dizi tersten sıralanıyor.
        var sonuc = (from c in dizi
                        orderby c descending
                        select c);

        // Birden fazla alana göre sıralanıyor.
        // İlk olarak değere, daha sonra kategoriye göre sıralanır. (sondan başa doğru)
        var sonuc = (from c in urunler
                        orderby c.Kategori, c.Deger descending
                        select c);

        // Lambda Syntax
        var sonuc = urunler.OrderByDescending(c => c.Deger).ThenBy(c => c.Kategori);

Birleştirme (Join)

        // İki liste birleştirilerek, listelerin sadece belirli özellikleri alınıyor.
        var sonuc = (from c in dizi
                        join urun in urunler on c equals urun.Numara
                        select new
                        {
                            c,
                            urun.Ad
                        });

        // Left join
        var sonuc = (from c in dizi
                        join u1 in urunler on c equals u1.Numara into u2
                        from urun in u2.DefaultIfEmpty()
                        select new
                        {
                            c,
                            urun.Ad
                        });

Gruplama (Group)

        // Ürünler kategorilerine göre gruplanıyor.
        // Her bir kategori grubunda kaç adet ürün bulunduğu ve kategorinin toplam değeri listeleniyor.
        var sonuc = (from c in urunler
                        group c by c.Kategori into g
                        select new
                        {
                            Kategori = g.Key,
                            Adet = g.Count(),
                            ToplamDeger = g.Sum(k => k.Deger)
                        });

        // Birden fazla alana göre gruplama
        var sonuc = (from c in urunler
                        group c by new { c.Ad, c.Kategori } into g
                        select new
                        {
                            g.Key.Kategori,
                            Adet = g.Count(),
                            ToplamDeger = g.Sum(k => k.Deger)
                        });
Etiketler:  C#

C# Nesne Özelliklerine Varsayılan Değer Atama

tip

Bir nesne üzerindeki özelliklerin varsayılan değerlerini atama işlemi yapıcı içerisinde yapılmaktadır. C# 6.0 ile beraber bu işlem, artık özelliğin tanımlandığı yerde yapılabilmektedir.

Eski kullanım

    public class Ogrenci
    {
        public int Numara { get; }
        public string AdSoyad { get; set; }

        public Ogrenci()
        {
            this.Numara = 3;
            this.AdSoyad = "Selami Güngör";
        }
    }

Yeni kullanım

    public class Ogrenci
    {
        public int Numara { get; } = 3;
        public string AdSoyad { get; set; } = "Selami Güngör";
    }
Etiketler:  C#

C# 6.0 Null Kontrolü

tip

Bir nesnenin özelliklerine ya da metotlarına erişmeden önce, nesne değerinin null olup olmadığının kontrol edilmesi gerekmektedir. Aksi halde NullReferenceException hatası fırlatılır.

Örneğin, str adı tanımlanmış bir string nesnesinin uzunluğu alınmak isteniyor. Uzunluk alınmadan önce ilk olarak str değerinin null olup olmadığının kontrol edilmesi gerekiyor. C# 6.0 ile beraber, bu kontrol aşağıdaki gibi ?. operatörü ile yapılabilir.

var length = str?.Length;

İşlem sonunda, eğer str değeri null ise, null değeri döndürülür. Aksi halde string uzunluğu elde edilir.

Etiketler:  C#

Generic Singleton Pattern & C#

Generic Singleton pattern with C# and .NET 4 (or higher)

// T is a class and must have a public default constructor.

public sealed class Singleton<T> where T : class, new()
{
    private static readonly Lazy<T> instance = new Lazy<T>(() => new T());
        
    public static T Instance
    {
        get
        {
            return instance.Value;
        }
    }

    private Singleton() { }
}

Usage:

var myClass = Singleton<MyClass>.Instance;
Etiketler:  C#

Julia Fraktal Çizimi & C#

Fraktal; matematikte, çoğunlukla kendine benzeme özelliği gösteren karmaşık geometrik şekillerin ortak adıdır. En bilinen fraktal kümelerinden birisi olan Julia kümesinin C# ile oluşturulmuş hali aşağıdadır.

julia

using System.Drawing;
using System.Numerics;

namespace SG.Algoritma
{
    public class JuliaFractal
    {
        // Julia kümesinde, yarıçağı 2'den büyük her karmaşık sayı çemberi sonsuza götürmektedir.
        private const int MaxMagnitude = 2;

        // Maksimum iterasyon sayısı
        private const int MaxIterations = 1000;

        // Karmaşık sayı koordinat sisteminde, Julia kümesinin bölgesi.
        // Julia kümesinin sadece bir kısmını çizmek için farklı bir bölge verilebilir. 
        private static Complex AreaMin = new Complex(-2, -2);
        private static Complex AreaMax = new Complex(2, 2);

        private Complex C;

        public JuliaFractal(Complex c)
        {
            this.C = c;
        }

        /// <summary>
        /// Julia kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="dimension">Oluşacak imajın genişlik ve yükseklik değeri (Kare imaj oluşturulacak)</param>
        public Bitmap GenerateBitmap(int dimension)
        {
            return this.GenerateBitmap(dimension, JuliaFractal.AreaMin, JuliaFractal.AreaMax);
        }

        /// <summary>
        /// Julia kümesi imajı oluşturuluyor
        /// </summary>
        /// <param name="width">Oluşacak imajın genişliği. Yükseklik, çizilmek istenen bölgeyenin genişlik ve yükseklik değerlerine bakılarak belirlenecek.</param>
        /// <param name="areaMin">Karmaşık sayo kooordinat sisteminde, Julia kümesinin sadece belirli bir bölgeye karşılık düşen kısmı çizdirilmek istendiği zaman, bu bölgenin sol alt kösesi</param>
        /// <param name="areaMax">Sağ üst köşe</param>
        public Bitmap GenerateBitmap(int width, Complex areaMin, Complex areaMax)
        {
            var height = (int)(width * (areaMax - areaMin).Imaginary / (areaMax - areaMin).Real);

            // Boş bir bitmap oluştur
            var bitmap = new Bitmap(width, height);

            // Oluşturulacak imajın her piksel değerine karşılık düşen karmaşık sayı oluşturulacak.
            // Oluşturacağımız karmaşık sayıların, seçtiğimiz bölge içerisinde kalması gerekmektedir.

            var rScale = (areaMax - areaMin).Real / width;
            var iScale = (areaMax - areaMin).Imaginary / height;

            for (var x = 0; x < width; x++)
            {
                // Karmaşık sayısının real kısmı
                var real = areaMin.Real + x * rScale;

                for (var y = 0; y < height; y++)
                {
                    // Karmaşık sayısının imaginary kısmı
                    var imaginary = areaMin.Imaginary + y * iScale;

                    // Julia kümesi iterasyon değeri hesaplanıyor.
                    var iteration = this.CalculateIteration(new Complex(real, imaginary));

                    // Iterasyon değerine göre noktanın rengi ayarlanıyor.
                    bitmap.SetPixel(x, y, JuliaFractal.GetColor(iteration));
                }
            }

            return bitmap;
        }

        private int CalculateIteration(Complex z)
        {
            var iteration = 0;

            while (iteration < JuliaFractal.MaxIterations && z.Magnitude < JuliaFractal.MaxMagnitude)
            {
                z = z * z + this.C;
                iteration++;
            }

            return iteration;
        }

        /// <summary>
        /// // Iterasyona karşılık renk seçiliyor.
        /// </summary>
        private static Color GetColor(int iteration)
        {
            // Rasgele bir renk seçiliyor.
            // 256 tane rengin olduğu bir liste oluşturularak, listeden iteration % 256. renk de seçilebilir.
            // Ya da renk oluşturmak için farklı bir yöntem izlenebilir.

            return Color.FromArgb(0, iteration % 256, 0);
        }
    }
}

Julia kümesini fraktal resmini oluşturmak için, ilgili metot aşağıdaki şekilde çağrılabilir. Bu durumda en üstte yer alan resim oluşacaktır.

var fractal = new JuliaFractal(new Complex(0.285, 0.01));
var bitmap = fractal.GenerateBitmap(800);

bitmap.Save(@"D:\julia.png", ImageFormat.Png);

Julia fraktalının sadece belirli bir bölgesini çizdirmek için, ilgili metot aşağıdaki şekilde çağrılabilir. Böylece fraktalın istenilen bölgesi daha detaylı bir şekilde çizdirilebilir.

var bitmap = fractal.GenerateBitmap(800, new Complex(-0.85, 0.1), new Complex(-0.45, 0.37));

julia

Etiketler:  C#
Sayfa 1 2

Kategoriler

Algoritma (5), Cheat Sheet (2), Framework (3), İpucu (5), Kendime Not (1), Kitap (4), Kod (5), Matematik (1), Proje (5), Veritabanı (3), Workshop (3)

Etiketler

C# (13) HTML (1) JavaScript (2) SQL (3)

İngilizce / Türkçe

İngilizce / Türkçe kelime listesi kendime not