为参数类型一样返回类型不同的接口写一个泛型方法
2015-04-25 09:29
393 查看
Jeffrey Zhao真是神一样的存在,伊太结棍了(上海话),每次看他的博客得使劲使劲使劲地啃。本篇源于Jeffery Zhao的"逆泛型执行器"这篇文章。该文提到了为以下的接口写一个泛型方法:
public interface IRecord
{
string GetString(string field);
int GetInt(string field);
long GetLong(string field);
}先来实现该接口:
public class MyRecord : IRecord
{
public string GetString(string field)
{
return field + "--added string";
}
public int GetInt(string field)
{
return int.Parse(field + "1");
}
public long GetLong(string field)
{
return long.Parse(field);
}
}通常,在客户端这样调用:
static void Main(string[] args)
{
MyRecord myRecord = new MyRecord();
Console.WriteLine(myRecord.GetString("hello"));
Console.WriteLine(myRecord.GetInt("1"));
Console.WriteLine(myRecord.GetLong("2"));
Console.ReadKey();
}以上,对于IRecord接口的各个方法而言,它们处在同一个接口,有相同的方法参数,唯一不同的是返回类型,看来有必要请出泛型了。对于接口方法来说,接口就是它们的"天",它们得"一辈子"待在这里。而对于泛型而言,它以更高的视角来俯视接口和它的方法们。可能,我们需要这样一个针对IRecord接口的泛型方法:SomeExtenion.Get<T>(IRecord record, string str)。这里的T是什么,返回类型就是什么, 如果T是string类型,那就返回string类型,等等。输入参数就IRecord是接口和string类型。如何做呢?有这样的一个类的轮廓模模糊糊地出现在了脑海里:
public static class RecordExtensions
{
public static T Get<T>(IRecord record, string field)
{
}
}可是问题来了,如何返回T类型呢?Jeffrey Zhao给出了答案!
.NET 泛型的奇妙之处便在于其“动态”及“区分”。“动态”在于它可以于运行时进行具体化(相对于 C++ 里的“静态”),不过目前的问题不涉及这点。而“区分”则意味着不同的具体泛型参数,在 .NET 中都是不同的类型,拥有完全分离的元数据,例如方法表(Method Table),以及静态字段等等。
再次回到问题的本质:接口调用方法1,输入string类型参数,返回某个类型1;接口调用方法2,输入string类型参数,返回某个类型2......这不就是一个委托,这不就是Func<IRecord, string, T>吗?如果我们能把以下存储到某个地方该多好啊!(irecord, field) => irecord.GetString(field)
(irecord, field) => irecord.GetInt(field)
(irecord, field) => irecord.GetLong(field)当Get<T>调用的时候再把这些泛型委托取出来。Jeffery Zhao又给出了答案!
一个内部类 Cache,它起到了缓存的作用。
于是,再完善一下RecordExtensions这个类。public static class RecordExtensions
{
private static class Cache<T>
{
//委托类型字段,输入参数是IRecord和string类型,输出参数T
public static Func<IRecord, string, T> Get;
}
//构造函数中就往缓存中存数据
static RecordExtensions()
{
Cache<string>.Get = (irecord, field) => irecord.GetString(field);
Cache<int>.Get = (irecord, field) => irecord.GetInt(field);
Cache<long>.Get = (irecord, field) => irecord.GetLong(field);
}
public static T Get<T>(IRecord record, string field)
{
return Cache<T>.Get(record, field);
}
}以上,在静态类的静态构造函数中,把委托赋值给静态类中作为缓存的静态类Cache的委托类型的字段Get,由于.NET的“区分”性,缓存中的泛型委托拥有完全分离的元数据,当调用Get<T>方法的时候,会从缓存中取出对应的委托。最后,在客户端这样调用:
static void Main(string[] args)
{
MyRecord myRecord = new MyRecord();
Console.WriteLine(myRecord.GetString("hello"));
Console.WriteLine(myRecord.GetInt("1"));
Console.WriteLine(myRecord.GetLong("2"));
Console.WriteLine(RecordExtensions.Get<string>(myRecord, "hello"));
Console.WriteLine(RecordExtensions.Get<int>(myRecord, "1"));
Console.WriteLine(RecordExtensions.Get<long>(myRecord, "2"));
Console.ReadKey();
}通过调用接口方法和泛型方法,得到的结果是一样一样滴。Thanks, Jeffrey Zhao~~
相关文章推荐
- 返回多个不同类型参数的值(out)可变参数一维数组( params )把值从方法中带出(ref) 方法递归(方法自己调用自己与循坏类似注意return每次只能跳出一个方法))
- 我用C语言 写一个函数返回参数二进制中 1 的个数的三种不同方法
- 如何使一个函数或方法同时返回多个不同类型的值
- 在主函数中提示用户输入用户名和密码。另写一方法来判断用户输入是否正确。该方法分别返回一个bool类型的登录结果和和一个string类型的登录信息。如登录成功,返回true及“登录成功”,若登录失败则返回false及“用户名错误”或“密码错误”(使用out参数)
- 用一个方法返回两个及两个以上不同类型的结果
- C#取得一个函数或方法的参数类型参数名称返回值类型
- ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目
- 抽象类、接口、方法参数类型及返回值类型
- 一个类实现一个接口,可以重写接口中方法的参数类型吗?
- JAVA利用泛型返回类型不同的对象方法
- Android JAVA中如何利用泛型使方法动态返回不同类型
- 通过另类的泛型约束将两个输入输出参数不同的方法合并成一个方法的实现
- 如何通过一个方法来传入并处理不同泛型类型的集合
- Java 定义一个参数类型一样,但个数不固定的方法
- [VB.NET]问下 :自己写的com,其中一个接口方法返回一个variant类型的值,在.net中如何接收啊
- Java里如何实现一个方法在不同情况下“返回”不同的类型变量?
- C#只能靠参数而不能靠返回值类型的不同来区分方法重载
- 单元测试时候使用[ClassInitialize]会该方法必须是静态的公共方法,不返回值并且应采用一个TestContext类型的参数报错的解决办法
- Gson通过借助TypeToken获取泛型参数的类型的方法
- asp.net 参数不同共用一个页面的实现方法