Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将对象强制转换为IEnumerable<;T>;其中T未知_C#_Reflection - Fatal编程技术网

C# 将对象强制转换为IEnumerable<;T>;其中T未知

C# 将对象强制转换为IEnumerable<;T>;其中T未知,c#,reflection,C#,Reflection,我试图玩弄反思,遇到了以下情况 在下面的代码中,我们假设“obj”可以是IEnumerable或ICollection或IList类型 我想强制转换这个系统。对象总是IEnumerable(就像ICollection和IList从IEnumerable继承一样),这样我想枚举集合并使用反射来编写单个项 这背后的动机是,我只是想看看序列化程序通常是如何序列化数据的,所以我试图模拟这种情况,希望也能理解反射 我曾想过将对象强制转换为非泛型IEnumerable,但我认为这会导致不必要的对象装箱,比如

我试图玩弄反思,遇到了以下情况

在下面的代码中,我们假设“obj”可以是
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继承)