Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Generic programming
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
====Genericity in .NET [C#, VB.NET]==== Generics were added as part of [[.NET Framework#.NET Framework 2.0|.NET Framework 2.0]] in November 2005, based on a research prototype from Microsoft Research started in 1999.<ref>[https://docs.microsoft.com/en-us/archive/blogs/dsyme/netc-generics-history-some-photos-from-feb-1999 .NET/C# Generics History: Some Photos From Feb 1999]</ref> Although similar to generics in Java, .NET generics do not apply [[type erasure]],{{sfn|Albahari|2022}}{{rp|208β209}} but implement generics as a first class mechanism in the runtime using [[Reification (computer science)|reification]]. This design choice provides additional functionality, such as allowing [[Reflective programming|reflection]] with preservation of generic types, and alleviating some of the limits of erasure (such as being unable to create generic arrays).<ref>[https://www.ondotnet.com/pub/a/dotnet/2005/10/17/interview-with-anders-hejlsberg.html C#: Yesterday, Today, and Tomorrow: An Interview with Anders Hejlsberg]</ref><ref>[https://www.artima.com/intv/generics2.html Generics in C#, Java, and C++]</ref> This also means that there is no performance hit from runtime [[Type conversion|casts]] and normally expensive [[Boxing (computer science)|boxing conversions]]. When primitive and value types are used as generic arguments, they get specialized implementations, allowing for efficient generic [[Collection class|collections]] and methods. As in C++ and Java, nested generic types such as Dictionary<string, List<int>> are valid types, however are advised against for member signatures in code analysis design rules.<ref>[https://msdn.microsoft.com/en-us/library/ms182144.aspx Code Analysis CA1006: Do not nest generic types in member signatures]</ref> .NET allows six varieties of generic type constraints using the <code>where</code> keyword including restricting generic types to be value types, to be classes, to have constructors, and to implement interfaces.<ref>[https://msdn2.microsoft.com/en-us/library/d5x73970.aspx Constraints on Type Parameters (C# Programming Guide)]</ref> Below is an example with an interface constraint: <syntaxhighlight lang="csharp" line="1"> using System; class Sample { static void Main() { int[] array = { 0, 1, 2, 3 }; MakeAtLeast<int>(array, 2); // Change array to { 2, 2, 2, 3 } foreach (int i in array) Console.WriteLine(i); // Print results. Console.ReadKey(true); } static void MakeAtLeast<T>(T[] list, T lowest) where T : IComparable<T> { for (int i = 0; i < list.Length; i++) if (list[i].CompareTo(lowest) < 0) list[i] = lowest; } } </syntaxhighlight> The <code>MakeAtLeast()</code> method allows operation on arrays, with elements of generic type <code>T</code>. The method's type constraint indicates that the method is applicable to any type <code>T</code> that implements the generic <code>IComparable<T></code> interface. This ensures a [[compile time]] error, if the method is called if the type does not support comparison. The interface provides the generic method <code>CompareTo(T)</code>. The above method could also be written without generic types, simply using the non-generic <code>Array</code> type. However, since arrays are [[Covariance and contravariance (computer science)|contravariant]], the casting would not be [[type safe]], and the compiler would be unable to find certain possible errors that would otherwise be caught when using generic types. In addition, the method would need to access the array items as <code>object</code>s instead, and would require [[Type conversion|casting]] to compare two elements. (For value types like types such as <code>int</code> this requires a [[Boxing (computer science)|boxing]] conversion, although this can be worked around using the <code>Comparer<T></code> class, as is done in the standard collection classes.) A notable behavior of static members in a generic .NET class is static member instantiation per run-time type (see example below). <syntaxhighlight lang="csharp"> // A generic class public class GenTest<T> { // A static variable - will be created for each type on reflection static CountedInstances OnePerType = new CountedInstances(); // a data member private T _t; // simple constructor public GenTest(T t) { _t = t; } } // a class public class CountedInstances { //Static variable - this will be incremented once per instance public static int Counter; //simple constructor public CountedInstances() { //increase counter by one during object instantiation CountedInstances.Counter++; } } // main code entry point // at the end of execution, CountedInstances.Counter = 2 GenTest<int> g1 = new GenTest<int>(1); GenTest<int> g11 = new GenTest<int>(11); GenTest<int> g111 = new GenTest<int>(111); GenTest<double> g2 = new GenTest<double>(1.0); </syntaxhighlight>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)