首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测对象是否为ILookup<,>并打印它?

如何检测对象是否为ILookup<,>并打印它?
EN

Stack Overflow用户
提问于 2011-02-23 13:21:04
回答 3查看 288关注 0票数 3

我正在尝试制作一个非常初级的通用对象打印机,用于调试,灵感来自于你在LinqPad中获得的强大功能。

下面是我的print函数的伪代码。我的反射foo目前有点弱,当对象是一个ILookup时,我正在努力处理这种情况,因为我想枚举查找,打印每个键及其相关的集合。

ILookup没有非泛型接口,也没有实现IDictionary,所以我现在有点卡住了,因为我不能说o as ILookup<object,object>……在这个问题上,我想知道如何深入研究任何通用的interface...suppose,我希望有一个CustomObject<,,>的特例。

代码语言:javascript
复制
void Print(object o)
{
    if(o == null || o.GetType().IsValueType || o is string)
    {
         Console.WriteLine(o ?? "*nil*");
         return;
    }

    var dict = o as IDictionary;     
    if(dict != null)
    {
        foreach(var key in (o as IDictionary).Keys)
        {
            var value = dict[key];
            Print(key + " " + value);
        }
        return;
    }

    //how can i make it work with an ILookup? 
    //????????? 


    var coll = o as IEnumerable;
    if(coll != null)
    {
        foreach(var item in coll)
        { print(item); }
        return;
    }

    //else it's some object, reflect the properties+values
    {
        //reflectiony stuff
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-23 13:59:43

我不确定你到底想要实现什么,但是为了回答你的具体问题,你可以像这样使用反射:

代码语言:javascript
复制
public static void PrintIfLookup(object obj)
{
    if (obj == null)
        throw new ArgumentNullException("obj");

    // Find first implemented interface that is a constructed version of
    // ILookup<,>, or null if no such interface exists.
    var lookupType = obj
                    .GetType()
                    .GetInterfaces()
                    .FirstOrDefault
                     (i => i.IsGenericType &&
                           i.GetGenericTypeDefinition() == typeof(ILookup<,>));

    if (lookupType != null)
    {
        // It is an ILookup<,>. Invoke the PrintLookup method
        // with the correct type-arguments.

        // Method to invoke is private and static.
        var flags = BindingFlags.NonPublic | BindingFlags.Static;

        // Assuming the containing type is called Foo.
        typeof(Foo).GetMethod("PrintLookup", flags)
                   .MakeGenericMethod(lookupType.GetGenericArguments())
                   .Invoke(null, new[] { obj });
    }

}

private static void PrintLookup<TKey, TElement>(ILookup<TKey, TElement> lookup)
{
    // TODO: Printing logic    
}

我试图以这样一种方式编写它,以便您可以使用泛型以强类型的方式编写打印逻辑。如果您愿意,您可以进行更多的反射,以获取查找中每个IGrouping<,>的键和值。

编辑:顺便说一句,如果您使用的是C# 4,则可以将if语句的整个主体替换为:

代码语言:javascript
复制
PrintLookup((dynamic)obj);
票数 4
EN

Stack Overflow用户

发布于 2011-02-23 14:01:11

多态性可能会使您的代码变得更简单。

代码语言:javascript
复制
void Print(IDictionary dict)
{
    foreach (var key in dict.Keys)
    {
        var value = dict[key];
        Print(key + " " + value);
    }
}

void Print(object o)
{
    if (o == null || o.GetType().IsValueType || o is string)
    {
        Console.WriteLine(o ?? "*nil*");
        return;
    }
}

void Print(string s)
{
    Console.WriteLine(s);
}

void Print(IEnumerable ie)
{
    foreach (dynamic obj in ie)
    {
        Print(obj);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2011-02-23 13:52:41

要确定该类型使用反射实现某些泛型接口,请执行以下操作:

代码语言:javascript
复制
var objType = o.GetType();

// get the ILookup<,> interface type (if the type implements it)
var lookupInterface = objType.GetInterface("System.Linq.ILookup`2");

// the type implemented the interface if returned non-null value
var isILookup = lookupInterface != null;

泛型类型的名称损坏的模式为

代码语言:javascript
复制
type_name`generic_parameter_count

对于泛型类型的特定实例:

代码语言:javascript
复制
type_name`generic_parameter_count[type_name_1,...,type_name_n]

在本例中,ILookup<,>有两个参数,所以它是:

代码语言:javascript
复制
System.Linq.ILookup`2

我们对确切的实例不感兴趣,所以我们不需要指定类型参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5087314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档