• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
works guo

成功的渴望与生俱来---- 成功是获得赞美与尊重的最有效的途径
博客园    首页    新随笔    联系   管理    订阅  订阅

LINQ to Reflection(翻译)

(1)Loading up assemblies for searching (2)Finding generic delegates (3)Context 和 IDisposable
[索引页]



今天有空就研究一下LINQ和泛型,Reflection的应用,看见一篇很好的文章就翻译过拉!


LINQ to Reflection
地址



LINQ是很好的东西,允许我们查任何实现IEnumerable<T>对象.其中包括List<T>,Collection<T>,和其他更多的.很多查询操作符号都是拉反射返回数组,接下来我使用的这些LINQ 操作符就是.


Loading up assemblies for searching




首先,我想加载一些assemblies去搜索,这很容易的就发现使用System.Reflection.Assembly.LoadWithPartialName,可是这个方法是.NET推荐使用的方法.但这个方法将满足简单达到搜索要求.我不想使用写代码的方式.

首先带来的就是一个要搜索的assembly名的清单并把他们放入的数组.

string[] assemblyNames = { "System", 
                 
"mscorlib", 
                 
"System.AddIn",
                 
"System.Configuration", 
                 
"System.Core", 
                 
"System.Data",
                 
"System.Data.Entity",
                 
"System.Data.Entity.Design",
                 
"System.Data.Linq",
                 
"System.Deployment",
                 
"System.Design",
                 
"System.DirectoryServices",
                 
"System.DirectoryServices.Protocols",
                 
"System.Drawing",
                 
"System.Drawing.Design",
                 
"System.EnterpriseServices",
                 
"System.IdentityModel",
                 
"System.IdentityModel.Selectors",
                 
"System.Management",
                 
"System.Management.Instrumentation",
                 
"System.Messaging",
                 
"System.Printing",
                 
"System.Runtime.Remoting",
                 
"System.Runtime.Serialization",
                 
"System.Security",
                 
"System.ServiceModel",
                 
"System.ServiceProcess",
                 
"System.Transactions",
                 
"System.Web", 
                 
"System.Web.Services", 
                 
"System.Windows.Forms", 
                 
"System.Workflow.Activities", 
                 
"System.Workflow.ComponentModel", 
                 
"System.Workflow.Runtime", 
                 
"System.WorkflowServices", 
                 
"System.Xml", 
                 
"System.Xml.Linq"
             }
;

都是非长漂亮的.NET Framework 3.5 assemblies,下一步,我要创建一个LINQ 查询去查询加载上的的assemblies,所以我能执行搜索这些assemblies.这是使用扩展方法:

var assemblies = assemblyNames.Select(name => Assembly.LoadWithPartialName(name));


下面是查询语法方式:

var assemblies = from name in assemblyNames
            select Assembly.LoadWithPartialName(name);


assemblies是变量,我们能在被加载assemblies中的执行查询.


Finding generic delegates




我已经体验一个API,并且如果我要知道现在有的.NET中的generic delegate.我们使用LINQ 表达方式很轻易的从已经加载的assemblies中得到.但首先,我需要知道怎样查找.我只能加载generic delegate到已经知道Type object中.

Type actionDelegate = typeof(Action<>);


当我加载一个generic delegate 进入一个Type对象中时,我注意一些关键属性,如"IsGenericType" and "IsPublic"这两个属性能决定它是否是generic,但不能决定是delegate,不幸运的是没有"IsDelegate",但我们可以转而使用IsSubclassOf(typeof(Delegate))返回"true".综合上面三个条件就能判定,我已经有一个predicate在我的搜索assemblies中使用.

var types = from name in assemblyNames
            select Assembly.LoadWithPartialName(name) into a
            from c 
in a.GetTypes()
            
where c.IsGenericType && c.IsPublic && c.IsSubclassOf(typeof(Delegate))
            select c;

foreach (Type t in types)
{
    Debug.WriteLine(t);
}


这里是LINQ同过一个附加部分("into a")结合在一起.这里首先查询枚举assembly名查询加载到assemblies.第二个查询在每一个assembly中调用"GetType"去查询加载的assembly类型,并且使用"where" clause在里面填充predicate就能很容易的筛选generic delegates.下面片段就结果.

System.EventHandler`1[TEventArgs]
System.Action`
1[T]
System.Comparison`
1[T]
System.Converter`
2[TInput,TOutput]
System.Predicate`
1[T]
System.Linq.Func`
1[TResult]
System.Linq.Func`
2[TArg0,TResult]
System.Linq.Func`
3[TArg0,TArg1,TResult]
System.Linq.Func`
4[TArg0,TArg1,TArg2,TResult]
System.Linq.Func`
5[TArg0,TArg1,TArg2,TArg3,TResult]


但并不是全部,但已经有的已经在这里拉.特别的是,我已经发现重载Action<T>,如同如果像Func<TResult>有多个委托声明时候样,可是这里没有,但你可以到计划重载Action匹配func.


Context 和 IDisposable




(I had a discussion with a team member that centered around types with names postfixed with "Context".)
已经讨论以命名后缀"Context'为中心的类型一组成员.我说明命名"Context"的类型隐含实现拉IDisposable,它被用来创建一个scope.
我只有通过得到一些真实的数据并找到在.NET Framework中被命名为"Context"还实现IDisposabble的来说明推测.下面是LINQ query

var types = from name in assemblyNames
            select Assembly.LoadWithPartialName(name) into a
            from c 
in a.GetTypes()
            
where (c.IsClass || c.IsInterface) && c.FullName.EndsWith("Context")
            group c.FullName by c.GetInterfaces().Contains(
typeof(IDisposable)) into g
            select 
new { IsIDisposable = g.Key, Types = g };


在查询中,我要查找所有以"Context"结尾的类型,并且按照是否实现IDisposable返回二进制的方式分组.并且我还取两个数据组合,并且anonymous types持有数据.下面可以输出结果.


foreach (var g in types)
{
    Debug.WriteLine(
string.Format("{0} types where IsIDisposable is {1}", g.Types.Count(), g.IsIDisposable));
    
if (g.IsIDisposable)
    
{
        
foreach (string t in g.Types)
        
{
            Debug.WriteLine(t);
        }

    }

}

并且最被找到说明我的论点不被支持.下面是输出结果.

144 types where IsIDisposable is False
50 types where IsIDisposable is True


我的左侧输出打印出所有的Context IDisposable类型,清单相当的长.我决定没有过滤non-public 类型,如MS 趋向产生有很多"internal"类型.所以它输出只有25%的以"Context"类型结尾的类型实现IDisposable,所以我的推断是错误的.


Other applications




LINQ provides a clean syntax to search assemblies using reflection.  I've also used it to argue against read-write properties for array types (they account for only 0.6% of all collection-type properties).  The continuations and joining lower the barrier for searching for specific types, properties, etc.  Since the LINQ methods are extension methods for any IEnumerable<T> type, you'll be pleasantly surprised when IntelliSense kicks in at the options available for querying and manipulating collections and arrays.



works guo 翻译

posted @ 2008-04-18 23:33  works guo  阅读(645)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3