Created Friday 10 January 2014
Generics
As far as I can tell, Java and C# generics are very similar with at least these differences:
- in C# you can use "base" types (pass by value) as generic types, resulting in performance gain
- while you can put upper bounds on generic types, C# has no concept of a lower bound
- generic methods with no params can't automatically deduce return type
Defining/Using Generic Classes
public class GenericClass<T> { T data; public GenericClass(T input) { //... } public void method1(T t) { // ... } public T method2() { // ... } } //... GenericClass<int> genericClass = new GenericClass<int>(5); //multiple generic types public class GenericClass<T,U> { //... }
Defining/Using Generic Methods
public class SomeClass { public T genericMethod<T>(T input) { // ... } } //... SomeClass someClass = new SomeClass(); int result1 = someClass.genericMethod<int>(5); int result2 = someClass.genericMethod(4); //type inference
Note: The compiler cannot infer type parameters only from a constraint or return value. Therefore type inference does not work with methods that have no parameters.
Constraints
//T must be an Employee or derive from Employee public class GenericClass<T> where T : Employee { //... } //T must be a struct public class GenericClass<T> where T : struct { //... } //T must be a class public class GenericClass<T> where T : class { //... }
//multiple constraints class EmployeeList<T> where T : Employee, IEmployee, new() { // ... } //constraints on multiple generic types class Test<T, U> where U : struct where T : new() { }
Note: When used as a generic constraint, new()
means that the generic type must have a public parameterless constructor. When used together with other constraints, the new()
constraint must be specified last.
Note: Don't use == or != operators for comparison on generic types with no constraints (unbounded type parameters) or those that use class
constraint. These comparisons will fail!
Generics and Value Types
In Java, if var
is a variable of type T (generic type), then var = null
is always valid. In C#, that statement isn't valid when T is a value type (int
, float
, etc). The solution is to use default
:
T var = default(T);
Multi-Threading
TODO
Reflection
TODO
LINQ
Language-Integrated Queries or LINQ generalizes query languages i.e., LINQ allows you to work with C# objects to access data structures such as databases or XML. LINQ supports at least these data sources:
- data from memory
- XML
- SQL databases.
A typical LINQ operation looks like this:
// 1. Data source. int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 }; // 2. Query creation. // numQuery is an IEnumerable<int> var numQuery = from num in numbers where (num % 2) == 0 orderby num select num; // 3. Query execution. foreach (int num in numQuery) { Console.Write("{0,1} ", num); }
- Use the Object Relational Designer to map database data to objects.
- See also: Basic LINQ Queries
- LINQ can also be used for data transformation
- Under the hood, LINQ queries use methods. The above example is equivalent to:
var numQuery2 = numbers .Where(num => num % 2 == 0) .OrderBy(n => n);
Resources
- Generics C# Programming Guide
- Introduction to Generics
- Constraints on Type Parameters
- Generic Methods
- Generics in the Runtime
- Getting Started With LINQ
- Basic LINQ Queries
- Data Transformations with LINQ
No backlinks to this page. comments powered by Disqus