Tuple, one of the concepts of functional programming, is seen in dynamic languages such as Elang, F #, and so on. However, the first time I heard that the tuple was still in the 2005 garden Ninputer Daniel proposed the basic idea of implementing tuple in. NET 2.0, we can admire the historical fragment at the following address:
Discussion on implementation methods of tuple in. NET 2.0
Thus, tuple is not a creation of. NET 4.0, but it is a necessary complement to the concept of C # tending to functional programming. So, let's start by looking at what is a tuple?
What is a tuple?
What is a tuple, in Chinese we translate it into tuples. The concept of a tuple is derived from a mathematical concept that represents an ordered set of data. In. NET, a tuple is implemented as a generic type, n-tuple represents a tuple with n elements, and the elements of the collection can be of any type, such as defining a 3-tuple that represents date (year, Month, day) when it can be defined as:
RELEASE:CODE01, 2009/05/29//Author : Anytao, Http://www.anytao.comvar date = tuple.create<int, int, int> (2 009, 5, 29);
by Tuple.create<int, int, int> will define an instance of Tuple<int, int, int>, which implements three data members:
For the specific parsing of the tuple we then analyze, now only a general understanding.
We can have two aspects of understanding, in. NET about tuple we have the following definition:
- In a broad sense, a tuple is a data structure, and usually the type and data of its members are determined.
- In the narrow sense, all the types that implement the Ituple interface are examples of tuple. In the. NET 4.0 BCL, 8 tuple types are predefined. For example, the simplest tuple definition is:
public class tuple<t1>: IStructuralEquatable, IStructuralComparable, IComparable, ituple{}
All other tuple types implement the Ituple interface, which is defined as:
interface ituple{ int Size {get;} int GetHashCode (IEqualityComparer comparer); String ToString (StringBuilder sb);}
In this interface, a read-only property is defined size, two overwrite methods GetHashCode, and ToString, which implements the interface of the tuple eight King Kong as follows:
public class Tuple<t1>public Class Tuple<t1, T2>public class Tuple<t1, T2, T3>public class Tuple<t1, T2, T3, T4>public class Tuple<t1, T2, T3, T4, T5>public class Tuple<t1, T2, T3, T4, T5, T6>public class Tu Ple<t1, T2, T3, T4, T5, T6, T7>public class Tuple<t1, T2, T3, T4, T5, T6, T7, trest>
Note: The Size property, the ToString (StringBuilder sb) method, are implemented as display interface methods, so they can only be accessed as interface instances, but ituple itself is defined internal, which means that we cannot access Ituple in the program, The He Yiho solution is not yet clear.
In the following definition, we encapsulate the custom request as a tuple:
RELEASE:CODE02, 2009/05/29//Author : Anytao, Http://www.anytao.compublic class myrequest{public tuple< String, Uri, datetime> getmyrequest () { return tuple.create<string, Uri, datetime> ("anytao.com", new Uri ("http://anytao.net/"), DateTime.Now);} }
Why should we use tuple? This is a tradeoff, and we can certainly create a new struct to encapsulate by 3-tuple the required request information in the Myrequest type above, both of which are competent. However, in practical programming practice, many times we need a flexible type of creating a certain data structure, many times the new data structure as a "temporary" role, through the new type of fuss is completely unnecessary, and the tuple is both designed for this kind of experience. For example:
- Point {X, Y}, which can represent the data structure of the coordinate location.
- Date {year, Month, day}, which can represent the structure of the dates, time {Hour, Minute, Second}, can represent a temporal structure, and datetime {date, time} can implement a flexible datetime structure.
- Request {Name, URL, Result}, which can represent some information about the request.
- 。。。 and take it on demand.
Tuple inside
In order to explore the tuple, we use the reflector tool to open the door of mystery, in terms of implementation, the tuple type is slightly thin, and there is no "magical" design to Tuple<t1, t2>, we can see its partial realization:
[Serializable]public class Tuple<t1, t2>: istructuralequatable, IStructuralComparable, IComparable, ITuple{ //Fields private T1 m_item1; Private T2 m_item2; Methods public Tuple (T1 item1, T2 item2) { this.m_item1 = item1; THIS.M_ITEM2 = item2; } String ituple.tostring (StringBuilder sb) { sb. Append (THIS.M_ITEM1); Sb. Append (","); Sb. Append (THIS.M_ITEM2); Sb. Append (")"); Return SB. ToString (); } int ituple.size { get { return 2; } } Properties public T1 Item1 { get { return this.m_item1; } } Public T2 Item2 { get { return this.m_item2; } } More ...}
Other tuple types are roughly the same, so it's easy to know how Item1, Item2 、...、 itemn are defined, and wondering where the size property will go, and what we expect from a foreach traversal of a tuple element, and what the future can expect.
However, for tuple, because of its limited number of elements, although it can meet most of the requirements, then the dynamic experience is our increasingly expected programming experience. At the same time, pay particular attention to the possible T5 of public class tuple<t1, T2, T3, T4, T6, T7, trest>, ArgumentException, for example:
RELEASE:CODE03, 2009/05/31//Author : Anytao, Http://www.anytao.comvar t8 = tuple.create<int, int, int, int, I NT, int, int, int> (1, 2, 3, 4, 5, 6, 7, 8); Console.WriteLine (T8. Rest);
Throws an exception:
Unhandled Exception:System.ArgumentException:The last element of a eight element tuple must is a tuple.
It is suggested that our final trest should be a tuple, so the modified program is:
RELEASE:CODE04, 2009/05/31//Author : Anytao, Http://www.anytao.comvar trest = tuple.create<int> (8); var T8 = tuple.create<int, int, int, int, int, int, int, tuple<int>> (1, 2, 3, 4, 5, 6, 7, trest); Console.WriteLine (T8. Rest);
There is no problem, for the reason we can easily find the answer from TUPLE<T1, T2, T3, T4, T5, T6, T7, trest> construction methods:
Public Tuple (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 Item7, Trest rest) { if (! ( Rest is Ituple) { throw new ArgumentException (Environment.getresourcestring ("Argumentexception_ Tuplelastargumentnotatuple ")); } This.m_item1 = item1; THIS.M_ITEM2 = item2; This.m_item3 = Item3; THIS.M_ITEM4 = ITEM4; THIS.M_ITEM5 = ITEM5; THIS.M_ITEM6 = ITEM6; This.m_item7 = Item7; This.m_rest = Rest;}
The Trest type parameter must be implemented as ituple, otherwise an exception is thrown. Trest to some extent for the expansion of the element to bring some convenience, but I think carefully, always feel here trest design a bit superfluous, since is the type parameter, T1, T2 、...、 tn In fact can be ituple instance, why not adhere to the last one.
between the gifted and the minor
Currently, there are only 8 predefined tuple types in. NET 4.0, so we should consider the possibility of moderately scaling for a tuple, but unfortunately the Ituple type is implemented as internal, so we cannot inherit ituple, but we have to customize a similar implementation:
The advantage lies in:
- Implementing multiple return value experiences for a method is obvious, and the tuple element can be used as the return value.
- Flexible construction of data structures, in line with the attendant spirit of public servants.
- Strongly typed.
Insufficient summary:
- Members of the current tuple type are implemented as deterministic values, and currently, there is no mechanism for dynamic resolution of the number of members if you have to tell me:-)
- public class Tuple<t1, T2, T3, T4, T5, T6, T7, Trest>, may raise ArgumentException.
"Goto" tuple tuples