返回一个通用的 IEnumerable<T>
Posted
技术标签:
【中文标题】返回一个通用的 IEnumerable<T>【英文标题】:returning a generic IEnumerable<T> 【发布时间】:2012-07-11 14:05:22 【问题描述】:我正在搞乱泛型和 IEnumerable,但我有点卡住了。 这是我正在尝试做的事情: 我想要一个返回任何集合类型的方法 - 实现 IEnumerable (?) - (例如:列表、堆栈、队列...)
此外,我希望能够返回任何数据类型的任何集合类型。
所以我希望这个方法能够返回一个List<string>,
以及一个Stack<int>
,以及一个List<double>
...等等等等。
public IEnumerable<T> returnSomething()
Stack<int> stackOfInts = new Stack<int>();
List<string> listOfStrings = new List<string>();
return stackOfInts;
这是我迄今为止尝试过的。但是这不起作用,我收到此错误:
Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?)
但是,如果我将方法签名中的 IEnumerable<T>
替换为 IEnumerable<int>
,我可以返回任何 int 类型的集合。然而这意味着,现在我不能再返回ListOfStrings
了。
将不胜感激任何建议或想法 :)
【问题讨论】:
【参考方案1】:您需要在方法中添加generic type parameter:
public IEnumerable<T> ReturnSomething<T>()
Stack<T> stackOfT = new Stack<T>();
return stackOfT;
类型参数出现在方法名称之后,但在参数之前。也可以有一个具有多个类型参数的方法。
调用方法时可以指定类型:
IEnumerable<int> myInts = ReturnSomething<int>();
【讨论】:
谢谢,这确实有效,但现在我似乎无法向堆栈中添加任何内容..stackOfInts.Push(3);如果我尝试这个,它会说:“最好的重载匹配......有一些无效的参数”。有什么想法吗? @JaneDoe:您只能将T
s 添加到Stack<T>
。 3 不一定是T
。除非您添加 generic type constraint,否则您不知道 T
是什么,因此您甚至无法构建一个 - 为此您需要一个 new()
约束。你想做什么,为什么需要这个?
我不需要这个来做任何特别的事情,我只是在尝试一堆东西。不过我现在明白了,谢谢。【参考方案2】:
诀窍是声明 <T>
对,如果你定义了泛型<T>
,那么你必须在你的方法中坚持它,所以如果你有IEnumerable<T>
,那么在你的其他地方您必须使用 <T>
而不是 <int>
或任何其他类型的方法。
只有在你真正使用你的泛型类型时,你才会用泛型<T>
替换一个真正的类型。
查看示例
class Foo<T>
public IEnumerable<T> GetList()
return new List<T>();
public IEnumerable<T> GetStack()
return new Stack<T>();
class Program
static void Main(string[] args)
Foo<int> foo = new Foo<int>();
IEnumerable<int> list = foo.GetList();
IEnumerable<int> stack = foo.GetStack();
Foo<string> foo1 = new Foo<string>();
IEnumerable<string> list1 = foo1.GetList();
IEnumerable<string> stack1 = foo1.GetStack();
【讨论】:
【参考方案3】:public IEnumerable<T> returnSomething()
Stack<int> stackOfInts = new Stack<int>();
return (IEnumerable<T>) stackOfInts;
【讨论】:
【参考方案4】:类型参数需要调用者在某处指定。
在实例化泛型类时:
public class MyClass<T>
public IEnumerable<T> returnSomething()
Stack<T> stackOfTs = new Stack<T>();
List<T> listOfTs = new List<T>();
return stackOfTs;
var v = new MyClass<int>();
foreach(var item in v.returnSomething())
或者在调用非泛型类的泛型方法时:
public class MyClass
public IEnumerable<T> returnSomething<T>()
Stack<T> stackOfTs = new Stack<T>();
List<T> listOfTs = new List<T>();
return stackOfTs;
var v = new MyClass();
foreach(var item in v.returnSomething<int>())
【讨论】:
【参考方案5】:更多帮助,完整结构如下...
我的模型是
public class Student
public int studentId get; set;
public string studentName get; set;
public string subject get; set;
public string studentClass get; set;
public int RollNumber get; set;
IEnumerable 返回数据列表
public static IEnumerable<Student> ReturnSomething()
IList<Student> studentList = new List<Student>()
new Student()
studentId = 1, studentName = "Bill", subject = "Science", studentClass = "nine", RollNumber = 01,
new Student()
studentId = 2, studentName = "Steve", subject = "Arts", studentClass = "ten", RollNumber = 03,
new Student()
studentId = 3, studentName = "Ram", subject = "Commerce", studentClass = "nine", RollNumber = 05,
new Student()
studentId = 1, studentName = "Moin", subject = "Science", studentClass = "ten", RollNumber = 06
;
return studentList;
最后一个是访问码
Student student = new Student();
IEnumerable<Student> studentList = ReturnSomething();
foreach (Student VARIABLE in studentList)
student.studentName += VARIABLE.studentName + " "+ "Class= ";
student.studentClass += VARIABLE.studentClass + " ";
Console.WriteLine(student.studentName + student.studentClass);
Console.ReadKey();
【讨论】:
【参考方案6】:是的,如果您更改 IEnumerable<T> to IEnumerable<dynamic>
,您可以返回任何类型
像这样:
public IEnumerable<dynamic> returnSomething()
.....
【讨论】:
这确实有点像黑客。我试过了,它也没有编译。 @codesparkle 我同意你的观点并强烈遵循它,但是在他们无法控制给定的第三方 API 方法返回类型的时候,动态是这样的救星案例 @JaneDoe 当你调用这样的方法时: IEnumerable以上是关于返回一个通用的 IEnumerable<T>的主要内容,如果未能解决你的问题,请参考以下文章
返回 IEnumerable<T> 与 IQueryable<T>
返回 IEnumerable<T> 与 IQueryable<T>