接收List的C#泛型方法不会为实际类型的T调用重载方法(更喜欢通用类型)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了接收List的C#泛型方法不会为实际类型的T调用重载方法(更喜欢通用类型),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1807字,纯文字阅读大概需要3分钟。
内容图文
参见英文答案 > why is this generic not resolved at compile time? 4个
我有这个例子C#代码:
class Stuff { } // empty class
void Main()
{
var list = new List<Stuff> {
new Stuff(),
new Stuff()
};
Fun(list);
}
void Fun<T>(List<T> a)
{
Debug.Log("called List<T> Fun");
foreach (T t in a) {
Fun(t);
}
}
void Fun(Stuff a)
{
Debug.Log("called Stuff Fun");
}
void Fun<T>(T a)
{
Debug.Log("called T Fun");
}
调用Main()最终打印:
called List<T> Fun
called T Fun
called T Fun
我不明白为什么编译器能够按预期调用Fun< T>(List< T> a),但后来不知道调用Fun(Stuff a),这比Fun< T>(T更具体)一个).在这种情况下,在编译时是否确定T是Stuff?在Fun< T>(List< T> a)中打印typeof(T)给出了“Stuff”如预期的那样,但这不是任何事情的证据……
添加Fun(List< Stuff> a)方法有效但不可取(项目中列表有许多不同的可能类型,并且所有这些行为都应该相同).
我试过搜索这个问题,但无法用我能找到它的方式来表达它.对不起,如果之前有人问过这个问题(可能!).
解决方法:
关键是要理解void Fun< T>(List< T> a)被编译一次,重载决议执行一次.不是每T一次,而是一次.
在编译此代码时考虑编译器的情况:
void Fun<T>(List<T> a)
{
Debug.Log("called List<T> fun");
foreach (T t in a) {
Fun(t);
}
}
特别是,考虑Fun(t)调用中的重载决策.
编译器对T一无所知,这是Fun(t)调用中参数的类型 – 它可以是任何非指针类型.它必须在这些签名之间执行重载解析:
void Fun<T>(List<T> a)
void Fun(Stuff a)
void Fun<T>(T a)
这些方法中唯一适用的是最后一个 – 调用代码中的T用作我们调用的方法中T的类型参数,并且没问题.其他两种方法不适用,因为没有从T到List< TList>的转换. (对于任何TList),或从T到Stuff.
如果您希望在执行时执行重载决策,则可以使用动态类型:
foreach (dynamic d in a) {
Fun(d);
}
我个人并不喜欢这样做,但在这种情况下它可能会做你想要的.另一方面,对于嵌套列表,它可能会变得棘手 – 如果你是一个List< int>,那么你期望它调用Fun< List< int>>(list)或Fun< int>(list)?老实说,我不记得规则,知道哪些是“更好”或是否含糊不清.
内容总结
以上是互联网集市为您收集整理的接收List的C#泛型方法不会为实际类型的T调用重载方法(更喜欢通用类型)全部内容,希望文章能够帮你解决接收List的C#泛型方法不会为实际类型的T调用重载方法(更喜欢通用类型)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。