3. LINQ (Language-Integrated Query)
• A query is an expression that retrieves data from a data source.
• All LINQ query operations consist of three distinct actions:
1. Obtain the data source
2. Create the query
3. Execute the query
var numbers = new[] {12, 3, 7, 4, 3, 1, 8, 22,
65, 33, 7, 9, 3, 3};
var evenNumbers = numbers.Where(x => x%2 == 0);
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
var numbers = new[] {12, 3, 7, 4, 3, 1, 8, 22, 65, 33,
7, 9, 3, 3};
var evenNumbers = numbers.Where(x => x%2 == 0)
.Select(x=> $"Number {x} is even.");
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
4. Example of Generic class
class Swapper<T>
{
public void Swap(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
}
Some type that can be passed into the class
5. Generic class usage
class Program
{
class SuperValue
{
public string Value { get; set; }
}
static void Main(string[] args)
{
int x = 12;
int y = 20;
SuperValue value1 = new SuperValue { Value = "Hello” };
SuperValue value2 = new SuperValue { Value = "World" };
Swapper<int> swapperOne = new Swapper<int>();
var swapperTwo = new Swapper<SuperValue>();
swapperOne.Swap(ref x, ref y);
swapperTwo.Swap(ref value1, ref value2);
Console.WriteLine($"x = {x}, y = {y}");
Console.WriteLine($"v1 = {value1.Value}, v2 = {value2.Value}");
Console.ReadLine();
}
}
6. Generic Constraints
By default, a type parameter can be substituted with any type whatsoever. Constraints can be
applied to a type parameter to require more specific type arguments:
where T : base-class // Base-class constraint
where T : interface // Interface constraint
where T : class // Reference-type constraint
where T : struct // Value-type constraint (excludes Nullable types)
where T : new() // Parameterless constructor constraint
where U : T // Naked type constraint
class Swapper<T> where T:class
{
public void Swap(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
}
Swapper<int> swapperOne = new Swapper<int>();
int is not a reference type!!!
7. System.Collections.Generic
List<string> names = new List<string>();
names.Add("John");
names.Add("Mike");
names.Add("Alan");
foreach (var name in names)
{
Console.WriteLine(name);
}
Dictionary<string,string> bouquet = new Dictionary<string, string>();
bouquet.Add("rose", "red");
bouquet.Add("tulip", "yellow");
bouquet.Add("chamomile", "white");
bouquet.Add("aster", "white");
Console.WriteLine($"Rose's color is {bouquet["rose"]}.");
Console.WriteLine("All flowers in bouquet.");
Console.WriteLine($"Total number is {bouquet.Count}");
foreach (var flower in bouquet)
{
Console.WriteLine($"{flower.Key} is {flower.Value}");
}
Console.WriteLine("White flowers are:");
foreach (var flower in bouquet.Where(x=>x.Value== "white"))
{
Console.WriteLine($"{flower.Key}");
}v
8. Attributes
• Attributes extend classes and types. This C# feature allows you to
attach declarative information to any type
class DisplayValueAttribute : Attribute
{
public string Text { get; set; }
}
class Record
{
[DisplayValue(Text="Name of the record")]
public string Name { get; set; }
public string Value { get; set; }
[DisplayValue(Text = "Created at")]
public DateTime Created { get; set; }
[Hide]
public DateTime Changed { get; set; }
}
public class HideAttribute : Attribute
{
}
9. Reflection
• Reflection objects are used for obtaining type information at runtime.
The classes that give access to the metadata of a running program are
in the System.Reflection namespace.
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);
System.Reflection.Assembly info = typeof(int).Assembly;
Console.WriteLine(info);