Microsoft Virtual Academy’de C# için En Çok Sorulan 10 Soruya Cevap
Selamlar;
Microsoft Virtual Academy’de en fazla sorulmuş soruların bir kısmına kendimce bu makalede cevaplamaya çalışacağım.
1-)Ne zaman Class ne zaman Struct kullanmalıyız ?
- Class’lar Heap bellekte referance değerleri ile tutulur.
- Struct’lar ise stack bellekte function ve data değerleri tutulur.
- Structlar genelde küçük datalar için kullanılırlar.
- Structlar çok daha performanslıdırlar.
- Structlar herzaman kendilerine özel dataları tutarlar. Adresleme yapamazlar.
- Structlar inheritance desteklemezler.
Aşağıda BaseCordinate adında bir class bir de BaseCordinateStruct adında struct olan iki yapı vardır. 2’sininde HomeX ve HomeY adında kordinat bilgileri constructerlarında atanmaktadı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 27 28 29 30 31 32 33 34 35 36 37 |
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BlogTips { public class BaseCordinate { public int HomeX { get; set; } public int HomeY { get; set; } public BaseCordinate(int x, int y) { HomeX = x; HomeY = y; } public override string ToString() { return "Başlangıç: " + $"({HomeX}) Bitiş: " + $"({HomeY})"; } } public struct BaseCordinateStruct { public int HomeX { get; set; } public int HomeY { get; set; } public BaseCordinateStruct(int x, int y) { HomeX = x; HomeY = y; } public override string ToString() { return "Struck Başlangıç: " + $"({HomeX}) Bitiş: " + $"({HomeY})"; } } |
Aşağıdaki ChangeMethodları constructerlarında class ve struct bekleyen iki methoddur. Amaç class ve struct yapıların propertyleri olan HomeX ve HomeY’yi değiştirip 10 arttırmaktır.
1 2 3 4 5 6 7 8 9 10 11 12 |
public static void ChangeMethod(BaseCordinate cor) { cor.HomeX += 10; cor.HomeY += 10; Console.WriteLine("Değişim: " + cor.ToString()); } public static void ChangeMethodStruck(BaseCordinateStruct cor) { cor.HomeX += 10; cor.HomeY += 10; Console.WriteLine("Değişim: " + cor.ToString()); } |
Aşağıdaki Main() methodunda BaseCordinate ve BaseCordinateStruct nesneleri yaratılıp kordinat değerleri 10 arttırılmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Program { static void Main(string[] args) { BaseCordinate cor = new BaseCordinate(10, 10); Console.WriteLine("İlk: " + cor.ToString()); BaseCordinateStruct corStruct = new BaseCordinateStruct(10, 10); Console.WriteLine("İlk: " + corStruct.ToString()); Console.WriteLine("".PadRight(40, '-')); ChangeMethod(cor); ChangeMethodStruck(corStruct); Console.WriteLine("".PadRight(40, '-')); Console.WriteLine("Son: " + cor.ToString()); Console.WriteLine("Son: " + corStruct.ToString()); Console.WriteLine("".PadRight(40, '-')); Console.ReadLine(); } } |
Sonuç ekranı aşağıdadır: Görüldüğü gibi ilk başta class ve struct yapıların kordinat değerleri 10 dur. Daha sonra ChangeMethod’u ile her iki yapınında kordinat değerleri 10 artırılmıştır. Ama bu sırada Class için referans değeri giderken struct için ise direk data kopyalanmıştır. Son olarak baştaki class ve struct değeri yazdırıldığında class’ın referans değeri değiştiği için artık son olan 20 değerini almıştır. Ama struct yapıda method içinde data direk kopyalandığı için eski değeri kalmış ve 10 sonucu dönmüştür. İşte class ve struct yapıların en belirgin farkı budur.
2-) Xml bir file’ı nasıl parse ederiz ?
Bunun için XmlDocument, XmlNode gibi yapılar kullanıp Xpath ile filter işlemi yapılabilir. Ama ben bugün farklı bir şekilde Xml’i DataSet’e doldurup Linq ile filitreleyeceğim:
Örnek Kurları gösteren today.xml aşağıdaki gibidir.
1 2 |
<?xml version="1.0" encoding="ISO-8859-9"?> <Tarih_Date Tarih="02.06.2015" Date="06/02/2015" Bulten_No="2015/105"><Currency CrossOrder="0" Kod="USD" CurrencyCode="USD"><Unit>1</Unit><Isim>ABD DOLARI</Isim><CurrencyName>US DOLLAR</CurrencyName><ForexBuying>2.6782</ForexBuying><ForexSelling>2.683</ForexSelling><BanknoteBuying>2.6763</BanknoteBuying><BanknoteSelling>2.687</BanknoteSelling><CrossRateUSD>1</CrossRateUSD><CrossRateOther></CrossRateOther></Currency><Currency CrossOrder="9" Kod="EUR" CurrencyCode="EUR"><Unit>1</Unit><Isim>EURO</Isim><CurrencyName>EURO</CurrencyName><ForexBuying>2.9425</ForexBuying><ForexSelling>2.9478</ForexSelling><BanknoteBuying>2.9404</BanknoteBuying><BanknoteSelling>2.9522</BanknoteSelling><CrossRateUSD></CrossRateUSD><CrossRateOther>1.0987</CrossRateOther></Currency><Currency CrossOrder="10" Kod="GBP" CurrencyCode="GBP"><Unit>1</Unit><Isim>Ä°NGÄ°LÄ°Z STERLÄ°NÄ°</Isim><CurrencyName>POUND STERLING</CurrencyName><ForexBuying>4.072</ForexBuying><ForexSelling>4.0933</ForexSelling><BanknoteBuying>4.0691</BanknoteBuying><BanknoteSelling>4.0994</BanknoteSelling><CrossRateUSD></CrossRateUSD><CrossRateOther>1.523</CrossRateOther></Currency></Tarih_Date> |
Aşağıda görüldüğü gibi dataset Xml’den gelen data ile doldurulup daha sonra Linq kullanılarak ‘US DOLLAR’ ve ‘EURO’ para birimlerinin fiyatları filitrelenerek çekilmiştir.
1 2 3 4 5 6 |
DataSet ds = new DataSet(); ds.ReadXml("file:///C:/Users/bkasmer/Desktop/today.xml"); var DolarPrice = (from row in ds.Tables[1].AsEnumerable() where row.Field<string>("CurrencyName") == "US DOLLAR" select row.Field<string>("ForexSelling")).FirstOrDefault(); var EuroPrice= (from row in ds.Tables[1].AsEnumerable() where row.Field<string>("CurrencyName") == "EURO" select row.Field<string>("ForexSelling")).FirstOrDefault(); |
3-)String ile string arasındaki fark nedir ?
İkisi de sealed class String sınıfından türemiştir.
- string değişken tanımlama amaçlı kullanılmalıdır.
- String daha çok methodlar veya referanslar için kullanılmalıdır.
Aşağıdaki örnek’te çıktılar aynıdır.
Ama aslında string.Concat methodu kullanılmamalıdır. Bunu yerine String.Concat() methodu kullanılmalıdır. Ayrıca değişken tanımlamada string name=”Bora” şeklinde kullanılmalıdır. String name2=”Bora 2″ şeklinde kullanılmamalıdır.
1 2 3 4 5 6 7 8 9 |
Console.WriteLine(typeof(string)); Console.WriteLine(typeof(String)); string name = "Bora"; String name2 = "Bora 2"; Console.WriteLine(name); Console.WriteLine(name2); Console.WriteLine(string.Concat(name, name2)); Console.WriteLine(String.Concat(name, name2)); Console.ReadLine(); |
4-)Console Application’da rooth path nasıl alınır ?
Console Application’da Rooth Path Reflection kullanılarak aşağıdaki gibi alınmıştır.
1 2 3 |
string path = System.Reflection.Assembly.GetExecutingAssembly().Location; Console.WriteLine(System.IO.Path.GetDirectoryName(path)); Console.ReadLine(); |
Ekran çıktısı: Aşağıdaki gibidir.
5-)Bir string içinde aranacak bir text değerin sayısını bulmanın en kısa yolu nedir?
Alttaki kodun ekran çıktısı 4dür. İlgili Text’in içinde aranacak string RegularExpression ile bulunup, adedi count özelliği ile ekrana yazdırılmıştır.
1 2 3 |
string input = "Test amaçlı yazılmış deneme yazıları duvara yazılmış, yazılım ekibi tarafından test edilmiştir."; Console.WriteLine(System.Text.RegularExpressions.Regex.Matches(input, "yazı").Count); Console.ReadLine(); |
6-)Bir Dictionary nesnesindeki elemanları isme göre nasıl sıralarız ?
Aşağıda görüldüğü gibi programlama dillerini barındıran dictionary nesnesi linq kullanılarak Key’e göre sıralanmıştır. Daha sonra önce sırasız dizi daha sonra sıralı dizi foreach ile gezilerek ekrana basılmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Dictionary<int, string> diction = new Dictionary<int, string>(); diction.Add(1, "C#"); diction.Add(4, "Ruby"); diction.Add(2, "Java"); diction.Add(3, "Swift"); diction.Add(5, "C++"); List<KeyValuePair<int,string>> dictList = diction.ToList(); var sorted = from entry in diction orderby entry.Key ascending select entry; foreach (var item in dictList) { Console.WriteLine("Key: " + item.Key + " Value: " + item.Value); } Console.WriteLine("".PadRight(40, '-')); foreach (var item in sorted) { Console.WriteLine("Key: " + item.Key + " Value: " + item.Value); } Console.ReadLine(); |
Ekran Çıktısı:
7-)Bir text’i şifreleme ve deşifreleme nasıl yapılır ?
Önce aşağıda görüldüğü gibi CreateDes ile şifreleme amaçlı kullanılacak password otomatik olarak verilen text password’e göre oluşturulur. MD5 ile TripleDES’e verilecek key oluşturularak, sonuçta şifreleme işleminde kullanılacak TripleDES sınıfı yaratılır.
EncrptString() methodunda önce şifrelenecek text, Byte[]’a çevrilir. Bu byte dizisini tutacak memoryStream oluşturulur. CreateDES() ile key ve TripleDES oluşturulur. Daha sonra CryptoStream() ile yazı şifrelenerek MemoryStream’e yazılır. En sonunda da bu şifrelenen stream yazılabilir bir string değere dönüştürülür.
DecrptString() methodunda EncrptString() methoduna benzer adımlar izlenirken tek fark CryptoStream()’de CreateEncryptor yerine CreateDecryptor kullanılır. Böylece şifrelenen text değer eski okunabilir halini alı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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System; using System.Text; using System.Security.Cryptography; using System.IO; namespace QuestionsBlog { class DESEncrypt { static TripleDES CreateDES(string key) { MD5 md5 = new MD5CryptoServiceProvider(); TripleDES des = new TripleDESCryptoServiceProvider(); des.Key = md5.ComputeHash(Encoding.Unicode.GetBytes(key)); des.IV = new byte[des.BlockSize / 8]; return des; } public string EncryptString(string plainText, string password) { byte[] plainTextBytes = Encoding.Unicode.GetBytes(plainText); MemoryStream myStream = new MemoryStream(); TripleDES des = CreateDES(password); CryptoStream cryptoStream = new CryptoStream(myStream, des.CreateEncryptor(), CryptoStreamMode.Write); cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); return Convert.ToBase64String(myStream.ToArray()); } public string DecryptString(string encryptedText, string password) { byte[] encryptedTextBytes = Convert.FromBase64String(encryptedText); MemoryStream myStream = new MemoryStream(); TripleDES des = CreateDES(password); CryptoStream decryptStream = new CryptoStream(myStream, des.CreateDecryptor(), CryptoStreamMode.Write); decryptStream.Write(encryptedTextBytes, 0, encryptedTextBytes.Length); decryptStream.FlushFinalBlock(); return Encoding.Unicode.GetString(myStream.ToArray()); } } } |
Aşağıdaki örnekte test amaçlı şifrelenecek text yazı DESEncrypt sınıfı ile şifrelenip tekrar deşifre edilerek ekrana basılmıştı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 27 28 29 30 31 32 33 34 35 36 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace QuestionsBlog { class Program { static void Main(string[] args) { string text = "Bu Şifrelenecek Bir Textdir. 05.06.2015"; Console.WriteLine("Şifrelenecek Yazı:"); Console.WriteLine("".PadRight(40, '-')); Console.WriteLine(text); Console.WriteLine(); string password = "12345"; DESEncrypt testEncrypt = new DESEncrypt(); string encText = testEncrypt.EncryptString(text, password); Console.WriteLine("Encrypted Text:"); Console.WriteLine("".PadRight(40, '-')); Console.WriteLine(encText); Console.WriteLine(); Console.WriteLine("Decrypted Text:"); Console.WriteLine("".PadRight(40,'-')); string plainText = testEncrypt.DecryptString(encText, password); Console.WriteLine(plainText); Console.ReadLine(); } } } |
Örnek ekran çıktısı aşağıdaki gibidir.
8-)Bir enumun string değeri value değerinden nasıl bulunur ?
Aşağıda Sehirler adında il key’leri ve il kodları value’leri olucak şekilde bir enum tanımlanmıştır.
1 2 3 4 5 6 7 8 |
public enum Sehirler { Istanbul=34, Ankara=06, Izmir=35, Trabzon=61, Konya=42 } |
Aşağıda kullanıcıdan bir il kodu girilmesi istenmiştir. Daha sonra Enum.GetName() methodu ile ilgili koda ait Enum.Key’i yani şehir adı girilen value değerine göre bulunup ekrana basılmıştır.
1 2 3 4 5 6 7 |
Console.Write("Bir İl Kodu Giriniz: "); string strKod = Console.ReadLine(); int kod = Convert.ToInt32(strKod); string str = Enum.GetName(typeof(Sehirler), kod); Console.WriteLine("Girilen Sehir Kodu :"+ kod+ " & Girilen Sehrin Adı =" + str); Console.ReadLine(); Console.ReadLine(); |
Örnek Ekran Çıktısı:
9-)Bir array dizide tekrarlayan değerleri nasıl temizleriz ?
Aşağıda örnek amaçlı hazırlanmış bir isim dizisi bulunmaktadır. Öncelikle tüm liste foreach ile gezilerek yazdırılmıştır. Daha sonra 1.Method olarak Linq kullanılmıştır. 2.Method olarakta boş bir dizi daha açılmış ve bu dizi içinde olmayan isimler eklenerek Unique bir dizi elde edilmiştir. Daha sonra bu 2 yöntem ile elde edilen diziler gezilerek ekrana yazdırılmıştı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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
string[] myArray = new string[] { "Bora", "Bora", "Duru", "Engin", "Ada", "Ada", "Secil", "Yeliz", "Yeliz", "Mehmet", "Mehmet" }; string[] filterArray = myArray.Distinct().ToArray(); List<string> filterList = new List<string>(); foreach (string name in myArray) { if (!filterList.Contains(name)) { filterList.Add(name); } } //Tüm Liste int s = 0; foreach (string item in myArray) { s++; Console.WriteLine(s.ToString() + "-) " + item); } Console.WriteLine(); Console.WriteLine("".PadRight(40, '-')); Console.WriteLine(); //1.Method string[] filterArray2 = filterList.ToArray(); int i = 0; foreach (string name in filterArray) { i++; Console.WriteLine(i.ToString() + "-) " + name); } Console.WriteLine(); Console.WriteLine("".PadRight(40, '-')); Console.WriteLine(); //2.Method int i2 = 0; foreach (string name2 in filterArray2) { i2++; Console.WriteLine(i2.ToString() + "-) " + name2); } Console.ReadLine(); |
Örnek Ekran Çıktısı:
10-)Bir method 2 değeri class kullanmamak kaydı ile nasıl geri döndürür ?
Aşağıda persons adında dictionary nesnesine örnek data amaçlı isim ve TC numaraları eklenmiştir. GetPersonDetail() string dönüş tipi olan bir methoddur. Ayrıca TCNo adında string out parametresi almaktadır. İlgili liste içinde random bir kayıt seçildikten sonra dictionary listesindeki Key yani isim döndürülürken Value değeri yani TCNo değeri out parametresine atanır. Böylece GetPersonDetail methodu sonucu 2 değer döndürülmüş olur. Yani dönüş tipi string iken out parametresine de ilgili değer atanarak amaca ulaşılmış olunur. İlgili dönen değerler ekrana aşağıdaki gibi yazdı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 |
public class Program { public static Dictionary<string, string> persons = new Dictionary<string, string>(); static void Main(string[] args) { persons.Add("Bora", "23412345678"); persons.Add("Murat","13445823170"); persons.Add("Ali", "61374892157"); string TCNo = string.Empty; string Name=GetPersonDetail(persons, out TCNo); Console.Write("İsim :" + Name + " | T.C : " + TCNo); Console.ReadLine(); } public static string GetPersonDetail(Dictionary<string, string> List, out string TCNo) { int count=(List).Count; Random rnd = new Random(); var per = List.Skip(rnd.Next(1, count)).FirstOrDefault(); TCNo = per.Value; return per.Key; } } |
Ekran Çıktısı:
Bu makalede Microsoft Virtual Academy’de ençok sorulan sorular içinden 10 tanesi seçip küçük kod örnekleri ile cevaplamaya çalıştım.
Yeni bir makalede görüşmek üzere hoşçakalın.
Programcılığın özü bu tür kodları yazmaktır zaten. Her durum için istenen işlemi gerçekleştirebilmek. 10 maddelik listeyi incelerken C++, bash, Perl ve Ruby aklıma geldi. Bazı maddeler C++, bash, Perl ve Ruby ‘de çok yaygın kullanılan işlemler C#’ta nasıl yapılır açıklaması gibi. Fakat tüm onlar arasından en çok 9. madde dikkatimi çekti cunku Ruby’de o işlem oldukça düşeş şekilde yapılıyor. Emacs’i açıp Ruby ‘de aynı işlemi yaptım, karşılaştırma olması açısından ekran görüntüsü.
http://i.hizliresim.com/ZDpk7Z.png
Selam Ömer;
Güzelmiş. Eline sağlık..
Blog’da ruby code’u da oldu sayende:)
Güzel örnekler Bora Hocam,
Örnek 9 benim de dikkatimi çekti. .Net ile haşır neşir olmayan insanlara .Net’in eğlenceli tarafını göstermek için “System.Linq.Enumerable.Distinct” methodunu kullanan bir örnek daha eklerseniz güzel olabilir.
Selamlar Hakan;
Öncelikle teşekkürler.
Enumerable.Distinct artık bir sonraki makaleye:)
İyi çalışmalar.
Merhabalar,
6. soruda ekstra bir sıralama işlemi yapmak yerine zaten bunun için tasarlanmış olan SortedDictionary kullanabiliriz:
var sorted = new SortedDictionary(diction);
foreach (var item in sorted)
Console.WriteLine(item);