什么是泛型(C#)

什么是泛型(C#)

所谓泛型是指将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。

一种类型占位符,或称之为类型参数。我们知道一个方法中,一个变量的值可以作为参数,但其实这个变量的类型本身也可以作为参数。泛型允许我们在调用的时候再指定这个类型参数是什么。在.net中,泛型能够给我们带来的两个明显好处是——类型安全和减少装箱、拆箱。 

  例如:通常一个方法或过程的签名都是有明确的数据类型的。
  如 :
  public void ProcessData(int i){}
  public void ProcessData(string i){}
  public void ProcessData(decimal i){}
  public void ProcessData(double i){}
  等。
  这些方法的签名中的:int ,string,decimal,double 都是明确的数据类型,程序员访问这些方法的过程中需要提供提定类型的参数:
  ProcessData(123);
  ProcessData("abc");
  ProcessData("12.12")
  而如果我们将int ,string,decimal,double这些类型也当成一种参数传给方法的时候方法的定义便是这样:
  public void ProcessData<T>(T i){} //T是int ,string,decimal,double这些数据类型的指代
  用户在调用的时候便成了这样:
  ProcessData<string>("abc");
  ProcessData<int>(123);
  ProcessData<double>(12.23);
  这与通常的那些定义的最大区别是,方法的定义实现过程只有一个。但是它具有处理不同的数据类型数据的能力。
  C# 2.0中有如List<>等泛型对象都具有此特性。
  具有泛型机制的软件开发平台及语言
  .Net 平台 2.0及以上版本
  JAVA 5及以上版本
  泛型的好处:

  泛型是c#2.0的一个新增加的特性,它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。它允许程序员将一个实际的数据类型的规约延迟至泛型的实例被创建时才确定。泛型为开发者提供了一种高性能的编程方式,能够提高代码的重用性,并允许开发者编写非常优雅的解决方案。

 

数据层:

public List<libs.Model.Artitle> GetAllArt()
       {
           List<libs.Model.Artitle> list = new List<Artitle>();
         
           string sqlconn = System.Configuration.ConfigurationSettings.AppSettings["sqlconn"];
           SqlConnection conn = new SqlConnection(sqlconn);
           string sqlstr = "select titleid,Title,author,company,Uploaddate,isVidate,conimages,content from writings order by titleid asc";
           SqlCommand cmd = new SqlCommand (sqlstr,conn);
          
           try
           {
               conn.Open();
               SqlDataReader reader = cmd.ExecuteReader();
               while (reader.Read())
               {
                   libs.Model.Artitle artles = new Artitle();
                   artles.Titleid = int.Parse(reader["titleid"].ToString());
                   artles.Title = reader["title"].ToString();
                   artles.Uploaddate = DateTime.Parse(reader["Uploaddate"].ToString());
                   list.Add(artles);
               }
           }
           catch (Exception ex)
           {
               throw new Exception(ex.Message);
           }
           finally
           {
               conn.Close();
           }
           return list;

       }

逻辑层:

 public List<Artitle> GettitleAll()
       {
           return new libs.DAL.ArtileAccess().GetAllArt();
       }

web层调用:

 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            this.GetallArt();
 
        }
    }

    public void GetallArt()
    {
        libs.Log.Artitless atrlesst = new libs.Log.Artitless();
        this.Repeater1.DataSource = atrlesst.GettitleAll(); //或者直接调用数据库层:

      //this.Repeater1.DataSource = new libs.DAL.ArtileAccess().GetAllArt();
        this.Repeater1.DataBind();
    }

 

 

泛型较为广泛地被讨论,这里写到的只是作为新手的入门级认识。

泛型最常应用于集合类。

泛型的一个显而易见的优点在于可以在许多操作中避免强制转换或装箱操作的成本或风险,拿ArrayList这个集合类来说,为了达到其通用性,集合元素都将向上转换为object类型,对于值类型,更是有装箱拆箱的成本:

static void Main(string[] args)

{

ArrayList al = new ArrayList();

al.Add(1);

}

在IL中是:

IL_0008:  ldc.i4.1

IL_0009:  box        [mscorlib]System.Int32

IL_000e:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)

box操作就是装箱,具体过程是把值类型从栈中弹出,放入堆中,同时把在堆中的地址压入到栈中,频繁出现这样的操作,成本比较大。


所以在2.0中,遇到以上的应用,应该使用泛型集合类List<T>:

static void Main(string[] args)

{

    List<int> l = new List<int>();

    l.Add(1);

}

 

另一个比较常用的泛型集合类是Dictionary<T,T>,用于保存键值对:

static void Main(string[] args)

{

    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict.Add(1, "SomeBook1");

    dict.Add(2, "SomeBook2");

    dict.Add(3, "SomeBook3");

 

    Console.WriteLine(dict[2]);//output:SomeBook2

    dict[2] = "SomeCD1";//modify

    Console.WriteLine(dict[2]);//output:SomeCD1

 

    dict.Remove(2);//delete

 

    foreach (KeyValuePair<int, string> kv in dict)

    {

        Console.WriteLine("Key = {0}, Value = {1}",kv.Key, kv.Value);

    }

}
转:http://blog.sina.com.cn/s/blog_4e6dffee0100bxty.html

### C#的概念 C#是一种参数化类的机制,它能够在类、结构体、方法以及委托中使用。通过引入,开发者可以定义具备通用行为的代码,这些代码能够适应多种数据类的需求[^2]。 例如,在不使用的情况下,如果要创建一个支持不同数据类的容器,则通常会依赖于 `object` 类或者接口实现。这种方式虽然可行,但在性能上存在开销,并且容易引发运行时错误。而借助,这些问题都可以得到解决。 --- ### 的定义方式 #### 1. **类** 可以通过在类名后面加上尖括号 `<T>` 来声明一个带有单个类参数 T 的类: ```csharp public class GenericClass<T> { private T value; public void Set(T newValue) { this.value = newValue; } public T Get() { return this.value; } } ``` 上述例子展示了如何创建一个简单的类 `GenericClass<T>`,其中 `Set` 方法用于设置值,而 `Get` 方法则返回存储的值。 #### 2. **方法** 除了类之外,还可以单独定义方法。这类方法不需要所属类本身是即可工作: ```csharp public static class UtilityMethods { public static T GetDefault<T>() { return default(T); } } // 调用示例: var defaultValue = UtilityMethods.GetDefault<int>(); Console.WriteLine(defaultValue); // 输出:0 ``` 这里展示了一个静态工具类中的方法 `GetDefault<T>()`,该方法接受任意类作为输入并返回对应类的默认值。 #### 3. **约束** 为了使更加灵活同时保持安全性,C# 提供了对的限制功能——称为“约束”。常见的几种约束如下所示: - **基类约束 (`where T : BaseClass`)** 如果希望某个仅限继承自特定基类的对象实例化,则可应用此约束条件。 - **接口约束 (`where T : IInterface`)** 此外也可以限定为实现了某接口的所有类。 - **构造函数约束 (`where T : new()`)** 当需要调用无参构造器初始化对象时需要用到这种形式。 下面是一个综合运用以上三种情况的例子: ```csharp public class Example<T> where T : Person, IPersonalInfo, new() { public T CreatePersonInstance(string name, int age) { var person = new T(); person.Name = name; person.Age = age; return person; } } ``` 在此处假设有一个名为 `Person` 的具体类及其关联接口 `IPersonalInfo` 存在的话,那么上面这段程序就可以正常编译运行[^1]。 --- ### 实际应用场景举例 考虑这样一个场景:我们需要维护一组整数列表并对它们求和;同样地也需要处理字符串数组连接成单一字符串的任务。此时如果不采用技术就需要分别针对每种情形重复编写相似逻辑。但如果利用好之后就能大大简化我们的开发过程。 ```csharp using System.Collections.Generic; class Program { static void Main(string[] args) { List<int> numbers = new List<int>{1, 2, 3}; Console.WriteLine(Sum(numbers)); // 结果应该是6 List<string> words = new List<string>{"hello", "world"}; Console.WriteLine(Concatenate(words)); // 结果应为helloworld } public static U ProcessList<U>(IEnumerable<U> items) { dynamic result = null; foreach (U item in items){ if(result == null){ result = item; }else{ result += item; } } return result; } public static int Sum(IEnumerable<int> nums){ return ProcessList(nums); } public static string Concatenate(IEnumerable<string> strs){ return ProcessList(strs); } } ``` 在这个样例里,我们先定义了一个通用的方法 `ProcessList<U>` ,它可以接收任何实现了 IEnumerable 接口的数据集合作为其参数。接着再基于这个基础构建专门用途更强些的新版本如计算总和或拼接文字串等功能模块[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值