C# 将对象强制转换为IEnumerable<;T>;其中T未知
我试图玩弄反思,遇到了以下情况 在下面的代码中,我们假设“obj”可以是C# 将对象强制转换为IEnumerable<;T>;其中T未知,c#,reflection,C#,Reflection,我试图玩弄反思,遇到了以下情况 在下面的代码中,我们假设“obj”可以是IEnumerable或ICollection或IList类型 我想强制转换这个系统。对象总是IEnumerable(就像ICollection和IList从IEnumerable继承一样),这样我想枚举集合并使用反射来编写单个项 这背后的动机是,我只是想看看序列化程序通常是如何序列化数据的,所以我试图模拟这种情况,希望也能理解反射 我曾想过将对象强制转换为非泛型IEnumerable,但我认为这会导致不必要的对象装箱,比如
IEnumerable
或ICollection
或IList
类型
我想强制转换这个系统。对象总是IEnumerable
(就像ICollection
和IList
从IEnumerable
继承一样),这样我想枚举集合并使用反射来编写单个项
这背后的动机是,我只是想看看序列化程序通常是如何序列化数据的,所以我试图模拟这种情况,希望也能理解反射
我曾想过将对象强制转换为非泛型IEnumerable,但我认为这会导致不必要的对象装箱,比如说IEnumerable
…我的想法正确吗
private void WriteGenericCollection(object obj)
{
Type innerType = obj.GetType().GetGenericArguments()[0];
//Example: IEnumerable<int> or IEnumerable<Customer>
Type generatedType = typeof(IEnumerable<>).MakeGenericType(innerType);
//how could i enumerate over the individual items?
}
private void WriteGenericCollection(对象obj)
{
类型innerType=obj.GetType().GetGenericArguments()[0];
//示例:IEnumerable或IEnumerable
Type generatedType=typeof(IEnumerable)。MakeGenericType(innerType);
//我怎样才能列举个别项目?
}
你的问题充满了误解。让我们把它们清理干净
在下面的代码中,假设“obj”可以是
IEnumerable
或ICollection
或IList
如果这是真的,并且您知道可枚举的类型,那么编写该方法的更好方法是
private void WriteGenericCollection<T>(IEnumerable<T> obj)
{
// ...
}
private void WriteGenericCollection(IEnumerable obj)
{
// ...
}
我想贬低这个系统。始终反对IEnumerable
(正如ICollection和IList从IEnumerable继承一样),因此
我想列举一下集合和使用反射
写下每个项目
当谈到接口时,“继承”不是一个正确的术语;它也可能给你错误的想法。接口最好被认为是契约:当考虑实现接口时,您只能决定按照作者的意图实现它,或者根本不实现它
一些接口是其他接口的超集;他们的合同规定“实施者必须在合同规定的任何其他内容之外做这件事”。但是从来没有像继承中常见的那样共享实现,因为接口没有任何共享
“向下投射”也不是你用这种方法所做事情的正确术语。向下转换意味着转换到更派生的类;还有对接口的转换:
// Note: the method is still generic!
private void WriteGenericCollection<T>(object obj)
{
var casted = (IEnumerable<T>)obj;
}
//注意:该方法仍然是泛型的!
私有无效WriteGenericCollection(对象obj)
{
var casted=(IEnumerable)obj;
}
我想将对象向下转换为非泛型IEnumerable,但是
认为这会导致不必要的对象装箱,当
比如说IEnumerable的实际例子……我想的对吗
private void WriteGenericCollection(object obj)
{
Type innerType = obj.GetType().GetGenericArguments()[0];
//Example: IEnumerable<int> or IEnumerable<Customer>
Type generatedType = typeof(IEnumerable<>).MakeGenericType(innerType);
//how could i enumerate over the individual items?
}
当且仅当对象是IEnumerable
且T
是a(数字类型、bool
、enum
或struct
)时,才会发生装箱。如果对象为一些已知的T
实现了IEnumerable
,那么您可以简单地将其强制转换为该对象。如果T
未知,则转换为非泛型IEnumerable
,并接受可能的性能影响(在任何情况下都无法避免)
如果您对对象一无所知,则只需要使用反射(在这种情况下,您当然还需要为无法枚举的对象制定计划,否则为什么首先允许将它们传递给您的方法?)。好吧,因为您直到运行时才知道项的实际类型,您不需要使用通用的
IEnumerable
接口;只需使用非泛型的一个,IEnumerable
(泛型继承自它):
由于装箱的原因,我希望避免使用IEnumerable..示例:在IEnumerable的情况下…我可以尝试执行“obj.GetType().GetGenericArguments()[0]”来获取实际的类型…不知道这是否有任何帮助?@KiranChalla,不,我看不出有什么帮助。。。如果不能静态地知道项目类型,那么使用泛型接口是无用的。在您的情况下,非泛型接口也可以为您服务,如果我想调用类似于
IEnumerable
的代码呢?谢谢Jon…在我的情况下,我不知道类型T…正如我提到的,我试图想象序列化程序如何序列化对象,因此当遇到泛型集合时,他们会怎么做…在我上面的场景中,假设对象总是可枚举的,以保持这里讨论的简单性…“继承”在谈论接口时不是一个正确的术语:我不同意;虽然类不从接口继承(它们实现了接口),但接口可以从其他接口继承(例如,ICollection从IEnumerable继承)