21 Mayıs 2018 Pazartesi

ValueTuple Sınıfı

Giriş
Value tuple C# 7 ile geldi. Açıklaması şöyle.
Value tuples are value types. They can't be null. The old Tuple type was a reference type
Value Tuple Ne Zaman Kullanılmaz
Şu noktalara dikkat etmek lazım.
Tuples are values, so are copied by value, rather than by reference
Tuple element names are not persisted
Tuple tipine reflection ile erişmek mümkün olmayabilir. Bir diğer açıklama şöyle.
Unfortunately C#7 value tuples cannot be used for data binding because they use fields, while Windows Forms standard data binding works only with properties.
Constructor - İsimsiz
Şöyle yaparız
System.ValueTuple<int, int> t = new System.ValueTuple<int, int>(0, 0);
Constructor - Value Tuple Listesi
Şöyle yaparız.
var list = new List<(int a, int b, int c)>()
{
  (1, 1, 2),
  (1, 2, 3),
  (2, 2, 4)
}
Constructor - İsimli
Açıklaması şöyle.
ValueTuple is just a normal C# type with no special support from the compiler. It's members are always called Item1, Item2 and so on. However, the (x, y) tuple syntax has special support from the compiler which introduces other names for the tuple members and maps them to the appropriate ValueType names in the generated IL code.
C# derleyicisini desteği ile ilgili açıklama şöyle
There are two different "kinds" of tuples involved here: the .NET ValueTuple<...> types, and C# tuple types. C# tuple types can have element names; ValueTuple<...> types can't. (There's simply nowhere in the type system for that to live in a normal way.)
Örnek
Şöyle yaparız.
(string x, int y) tuple1 = ("hello", 10);
(string a, int b) tuple2 = ("hello", 10);
Equals metodu
Value tuple reference olmadığı için aynı bir int'te olduğu gibi null ile karşılaştırılamaz. Bir başka value tuple ile aynı olup olmadığı karşılaştırılabilir.
Örnek
Şöyle yaparız.
var result=(new List<(int a, int b, int c)>()
{
  (1, 1, 2),
  (1, 2, 3),
  (2, 2, 4)
}
).FirstOrDefault(w => w.a == 4 && w.b == 4);

if (result.Equals(default(ValueTuple<int,int,int>)))
{
    Console.WriteLine("Missing!"); 
}
Örnek
Elimizde şöyle bir kod olsun.
(string foo, string bar) MyMethod() => default;

// Later
var result = MyMethod();
Şöyle yaparız.
result.Equals(default)
Örnek
Bu sınıfın generinc ve non-generic kodlar için farklı Equals metodu var. Şöyle yaparız.
if((1,2).Equals((2,1)))
{
    Console.WriteLine("It's true");
}
Item1, Item2 vs Alanları
Şöyle yaparız.
System.ValueTuple<int, int> t = ...;
int a = t.Item1;
int b = t.Item2;
Value Tuple Döndüren Metodlar
Örnek
Elimizde şöyle bir kod olsun
public (string name, int score) GetFoo()
Bu kod IL ile şöyle temsil edilir.
[TupleElementNames(new string[] { "name", "score" }]
public ValueTuple<string, int> GetFoo()
Örnek
Döndürülen Value Tuple değişkenlerine isim verileblir. Şöyle yaparız.
(double Latitude, double Longitude) getCoordinates()
{
    return (144.93525, -98.356346);
}
Örnek
Şöyle yaparız.
(double r1, double r2, double r3) perform(int p1, int p2)
Value Tuple ve Kalıtım
Açıklaması şöyle
Structures do not inherit in C#, so ValueTuple<T1>, ValueTuple<T1,T2>, ValueTuple<T1,T2,T3> and so on are distinct types that do not inherit from ValueTuple as their base. Hence, obj is ValueTuple check fails.
Bir nesnenin 2'li veya 3'lü ValueTuple olduğunu anlamak için şöyle yaparız.
private static readonly Set<Type> ValTupleTypes = new HashSet<Type>(
  new Type[] { typeof(ValueTuple<>), typeof(ValueTuple<,>),
               typeof(ValueTuple<,,>), typeof(ValueTuple<,,,>),
               typeof(ValueTuple<,,,,>), typeof(ValueTuple<,,,,,>),
               typeof(ValueTuple<,,,,,,>), typeof(ValueTuple<,,,,,,,>)
  }
);
static bool IsValueTuple2(object obj) {
  var type = obj.GetType();
  return type.IsGenericType
        && ValTupleTypes.Contains(type.GetGenericTypeDefinition());
}

Value Tuple Literal
Örnek
Şöyle yaparız. Foo metodu tuple type dönüyor. Return cümlesi is tuple literal.
public (int, string) Foo()
{
    //...
    return 7, "Done.";
}
Çağırmak için şöyle yaparız.
var (err, response) = Foo();

Hiç yorum yok:

Yorum Gönder