Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use generics in .NET

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article is about how generics are used in. Net. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

Understanding generics from simple examples

It is said that there is a film and television company to select the idol leading actor, the director said, the actor, height is king. So there is the following code:

/ / Actor entity class

Public class Boy

{

/ / name

Private string mName

/ / height

Private int mHeight

Public string Name {

Get {return this.mName;}

}

Public int Height {

Get {return this.mHeight;}

}

Public Boy (string name, int height) {

This.mName = name

This.mHeight = height

}

}

/ / Actor selection category

Public class Compare

{

/ / Director Supergirl was born and likes one-on-one competition.

Public Boy WhoIsBetter (Boy boy1, Boy boy2)

{

If (boy1.Height > boy2.Height)

{

Return boy1

}

Else

{

Return boy2

}

}

}

/ / Test

Static void Main (string [] args)

{

Boy boy1 = new Boy (Pan Changjiang, 165)

Boy boy2 = new Boy (Andy Lau, 175)

Console.WriteLine (new Compare () .WhoIsBetter (boy1, boy2) .Name)

Console.ReadLine ()

}

The code is very simple, Boy is the actor entity class, including name and height two field attributes; WhoIsBetter in the Compare class is the selection logic method, responsible for selecting the taller of the two actors; test results: Andy Lau wins.

The same is true in any industry, where demand changes are everywhere. The next day, need to choose the heroine, the director said, actress, slim is the king. So the code was changed, the actress entity class was added, and the actress selection method was added:

The copy code is as follows:

/ / add an actress entity

Public class Girl

{

/ / name

Private string mName

/ / body weight

Private int mWeight

Public string Name

{

Get {return this.mName;}

}

Public int Weight

{

Get {return this.mWeight;}

}

Public Girl (string name, int weight) {

This.mName = name

This.mWeight = weight

}

}

/ / add an actress method to the actor selection category

Public class Compare

{

/ / the actor's height is the king.

Public Boy WhoIsBetter (Boy boy1, Boy boy2)

{

If (boy1.Height > boy2.Height)

{

Return boy1

}

Else

{

Return boy2

}

}

/ / slim actresses are king

Public Girl WhoIsBetter (Girl girl1, Girl girl2)

{

If (girl1.Weight

< girl2.Weight) { return girl1; } else { return girl2; } } } //测试 static void Main(string[] args) { Boy boy1 = new Boy("潘长江", 165); Boy boy2 = new Boy("刘德华", 175); Girl girl1 = new Girl("巩俐", 120); Girl girl2 = new Girl("周迅", 80); Console.WriteLine(new Compare().WhoIsBetter(boy1, boy2).Name); Console.WriteLine(new Compare().WhoIsBetter(girl1, girl2).Name); Console.ReadLine(); } 结果选出了身高更高的刘德华,选出了体重更轻的周迅,导演很满意。但从程序设计角度,这段代码显然不够完美,第一天选男主角,第二天选女主角,往后还要选男配角,选女配角,选群众......按目前方式,只有往Compare类里不断添加方法才能满足导演需求,方法会越来越多,代码会越来越长。于是,我决定修改WhoIsBetter方法,让它以后可以支持男主,女主,男配,女配,男群众,女群众甚至支持所有两个对象之间的比较: 复制代码 代码如下: /// /// 男演员:实现IComparable接口 /// public class Boy : IComparable { //姓名 private string mName; //身高 private int mHeight; public string Name { get { return this.mName; } } public int Height { get { return this.mHeight; } } public Boy(string name, int height) { this.mName = name; this.mHeight = height; } public int CompareTo(object obj) { //比较身高 return this.mHeight - ((Boy)obj).Height; } } /// /// 女演员:实现IComparable接口 /// public class Girl : IComparable { //姓名 private string mName; //体重 www.jb51.net private int mWeight; public string Name { get { return this.mName; } } public int Weight { get { return this.mWeight; } } public Girl(string name, int weight){ this.mName = name; this.mWeight = weight; } public int CompareTo(object obj) { //比较体重 return ((Girl)obj).Weight - this.mWeight; } } 首先让实体类支持自定义的比较,男演员比较身高,女演员比较体重。自定义比较是通过实现IComparable接口完成的,在C#里但凡可以比较的类型,比如int、double、char等都实现了IComparable接口。关于IComparable接口此处不作详述,请读者自行查阅相关资料。 复制代码 代码如下: public class Compare { //万物皆object public object WhoIsBetter(object obj1, object obj2) { object result = obj2; //判断比较类型必须相同 if (obj1.GetType() == obj2.GetType()) { switch (obj1.GetType().ToString()) { //男演员选拔 case "Generic.Boy": if (((Boy)obj1).CompareTo(obj2) >

0)

{

Result = obj1

}

Break

/ / Actress selection

Case "Generic.Girl":

If ((Girl) obj1) .Compareto (obj2) > 0)

{

Result = obj1

}

Break

/ / extended int type comparison

Case "System.Int32":

If ((System.Int32) obj1) .Compareto (obj2) > 0)

{

Result = obj1

}

Break

}

}

Return result

}

}

The WhoIsBetter method is modified to not only support the comparison of actors and actresses, but also add a comparison of int types in order to show its expansibility.

The copy code is as follows:

/ / Test

Static void Main (string [] args)

{

Boy boy1 = new Boy (Pan Changjiang, 165)

Boy boy2 = new Boy (Andy Lau, 175)

Girl girl1 = new Girl (Gong Li, 120)

Girl girl2 = new Girl (Zhou Xun, 80)

Console.WriteLine (Boy) new Compare () .WhoIsBetter (boy1, boy2)) .Name)

Console.WriteLine (Girl) new Compare () .WhoIsBetter (girl1, girl2)) .Name)

Console.WriteLine (new Compare () .WhoIsBetter (boy1.Height, boy2.Height))

Console.WriteLine (new Compare () .WhoIsBetter (girl1.Weight, girl2.Weight))

Console.ReadLine ()

}

Test results:

Liu Dehua

Zhou Xun

one hundred and seventy five

one hundred and twenty

OK, so far, seems to be perfect, actor specific height, actress specific weight, but also supports int type ratio size, WhoIsBetter method has reusability, if necessary, can be expanded later to compare any two objects. Before generics, it did seem perfect, but this is only relative. Let's take a look at the weaknesses of the current code:

Weakness 1: reusability of methods

Suppose we want to make the WhoIsBetter method support more types, such as supporting basic double,char,bool types, supporting supporting role comparisons and mass comparisons that may be proposed by the director in the future, then we must constantly expand the internal code of the method, which brings great maintenance costs.

Weakness 2: type safety issues

The copy code is as follows:

/ / Test

Static void Main (string [] args)

{

Boy boy1 = new Boy (Pan Changjiang, 165)

Boy boy2 = new Boy (Andy Lau, 175)

Girl girl1 = new Girl (Gong Li, 120)

Girl girl2 = new Girl (Zhou Xun, 80)

Console.WriteLine (Boy) new Compare () .WhoIsBetter (boy1, girl1)) .Name)

Console.ReadLine ()

}

As in the above code, I compare Pan Changjiang with Gong Li. Although the omnipotent object brings us convenience and risks, this code can be compiled completely, but there will be exceptions at run time, and girl objects cannot be converted to Boy types. In reality, you can change to Korea, but not in the code. So this method is like a ticking time bomb, accidentally passing the wrong parameters, it will lead to serious consequences, and the compilation phase is completely undetected.

Weakness 3: performance problems caused by unpacking

When the int parameter is passed to the WhoIsBetter method, the conversion of object to int causes the unboxing operation:

If ((System.Int32) obj1) .Compareto (obj2) > 0)

Decompile to get MSIL:

IL_0093: unbox.any [mscorlib] System.Int32

C # is a strongly typed language, but Box and Unbox cannot be avoided as long as reference types are converted to value types. Readers are invited to consult the relevant materials for the knowledge of packing and unpacking, which will not be detailed here.

Understanding generics

OK, it's time for generics, an excerpt from the MSDN description of generics: generic classes and generic methods are reusable, type safe, and efficient, which non-generic classes and non-generic methods cannot. These three points are consistent with our above example.

Take a look at solutions that use generics:

The copy code is as follows:

Public class Compare where T: IComparable

{

Public T WhoIsBetter (T T1, T T2)

{

If (t1.CompareTo (T2) > 0)

{

Return t1

}

Else

{

Return t2

}

}

}

/ / Test

Static void Main (string [] args)

{

Boy boy1 = new Boy (Pan Changjiang, 165)

Boy boy2 = new Boy (Andy Lau, 175)

Girl girl1 = new Girl (Gong Li, 120)

Girl girl2 = new Girl (Zhou Xun, 80)

Console.WriteLine ((new Compare (). WhoIsBetter (boy1, boy2)) .Name)

Console.WriteLine ((new Compare (). WhoIsBetter (girl1, girl2)) .Name)

Console.WriteLine (new Compare () .WhoIsBetter (boy1.Height, boy2.Height))

Console.WriteLine (new Compare () .WhoIsBetter (boy1.Name, girl1.Name))

Console.ReadLine ()

}

This code outperforms non-generics in elegance and reusability, and it can be said to support all types of comparisons, as long as this type implements the IComparable interface and does not require any extension within the method once and for all.

Public class Compare where T: IComparable {

/ /...

}

The definition of a generic class is followed by the class name, which is generic-specific syntax, T represents the type passed in, and you can also replace it with other letters.

Where T: IComparable, literally, this paragraph represents a type constraint on T. The program is executed according to the human will, according to the previous example, if the program is inexplicably asked to compare two object, it has no way to know how to compare. So we have to tell the program that T must be a comparable type and T must implement the IComparable interface.

For generic parameter constraints, MSDN provides a table:

Constraint description

T: the structure type parameter must be a value type. You can specify any value type except Nullable.

T: the class type parameter must be a reference type; this also applies to any class, interface, delegate, or array type.

The T:new () type parameter must have a public constructor with no arguments. When used with other constraints, the new () constraint must be specified last.

T: the type parameter must be the specified base class or derive from the specified base class.

T: the type parameter must be the specified interface or implement the specified interface. Multiple interface constraints can be specified. Constraint interfaces can also be generic.

The type parameters provided by TRARU for T must be parameters provided for U or derived from those supplied for U.

Thank you for reading! This is the end of this article on "how to use generics in .NET". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report