如何遍历所有程序集中的成员、类

System.Reflection.Assembly类是一个比较常用到的类,在反射中就经常用到。

//第一种:此方法发射加载DLL文件获取Mapping类
            //string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("Colligate.DataSource.ServiceMonitor.DLL", "Colligate.AddIn.Application.Mapping.dll").Replace("file:///", "");
            //Assembly asm = Assembly.LoadFile(assembleFileName);

            //第二种:此方法通过程序集获取到Mapping类
            Assembly asm = Assembly.Load("Colligate.DataSource.ServiceMonitor");


            var typesToRegister = asm.GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }



注意在Assembly里面的加载程序集有3个方法,分别是Load、LoadFrom和LoadFile。这3个方法有什么异同呢?

  1. 如果你引用了命名空间,那么就直接Load()方法,参数里面写上命名空间+类名就可以加载了。
  2. 如果仅仅知道一个dll文件的那么就要用LoadFrom()方法了,参数里面直接填写完整的路径。

  LoadFrom 方法具有以下缺点。请考虑改用 Load。

  • 如果已加载一个具有相同标识的程序集,则即使指定了不同的路径,LoadFrom 仍返回已加载的程序集。 
  • 如果用 LoadFrom 加载一个程序集,随后加载上下文中的一个程序集尝试加载具有相同显示名称的程序集,则加载尝试将失败。对程序集进行反序列化时,可能发生这种情况。

  总结: LoadFrom只能用于加载不同标识的程序集, 也就是唯一的程序集, 不能用于加载标识相同但路径不同的程序集。

  3.LoadFile 加载指定路径上的程序集文件的内容。

  这个方法是从指定的文件来加载程序集,它是调用外部的API实现的加载方式,和上面Load,LoadFrom方法的不同之处是这个方法不会加载此程序集引用的其他程序集,也就是不会加载程序的依赖项。而同时也是不能加载相同标识的程序集的。

  4.GetExecutingAssembly获取当前正在执行的程序集。


static void Main(string[] args)
        {
            //需引用命名空间
            Assembly assm = Assembly.Load("fanshe");
            Console.WriteLine(assm.FullName);   //输出 fanshe, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

            //依靠路径
            Assembly assm1 = Assembly.LoadFrom(@"D:\fanshe.dll");
            Console.WriteLine(assm1.FullName);      输出 fanshe, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

            //与Assembly.LoadFrom基本一样,只是如果被加载的dll,还依赖其他的dll的话,被依赖的对象不会加载
            Assembly assm2 = Assembly.LoadFile(@"D:\fanshe.dll");
            Console.WriteLine(assm2.FullName);

            //当前正在执行的程序集
            Assembly assm3 = Assembly.GetExecutingAssembly();
            Console.WriteLine(assm3.FullName);

            Console.ReadKey();
        }



二、读取程序集中嵌入的资源

  读取嵌入的资源,主要有如下两个方法:

  1. GetManifestResourceNames:读取嵌入的资源名称。
  2. GetManifestResourceStream:读取嵌入的资源为流。
static void Main(string[] args)
        {
            Assembly ass = Assembly.LoadFrom(@"D:\test.dll");
            string[] names = ass.GetManifestResourceNames();
            foreach (string name in names)
            {
                Console.WriteLine("所有的嵌入资源名:" + name);
            }

            Stream myStream = ass.GetManifestResourceStream("Test.1.txt");
            Console.WriteLine();
            using (StreamReader sr = new StreamReader(myStream, Encoding.Default))
            {
                //嵌入的资源1.txt的内容
                Console.WriteLine("嵌入的资源1.txt的内容:" + sr.ReadToEnd());
            }
            
            Console.ReadKey();
        }










  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,使用foreach遍历字典时是不能直接修改字典的。这是因为foreach遍历是基于字典的快照进行的,所以对字典的修改不会在遍历中反映出来。如果要在遍历过程中修改字典的成员,可以使用for循环和索引来实现。例如,可以使用for循环和ElementAt方法来遍历字典并修改成员。\[1\] ```csharp for (int i = 0; i < dict.Count; i++) { var item = dict.ElementAt(i); int key = item.Key; string value = item.Value; // 在这里对字典的成员进行修改 // ... } ``` 如果在遍历过程中需要删除某些元素,可以使用for循环和Remove方法来实现。但是需要注意的是,删除元素后字典的长度会改变,所以在删除元素后,需要将索引i减1,以便正确遍历下一个元素。\[2\] ```csharp for (int i = 0; i < dict.Count;) { var item = dict.ElementAt(i); Console.WriteLine(item.Key.ToString() + " " + item.Value.ToString()); if (item.Key == 3 || item.Key == 4) { dict.Remove(item.Key); } else { i++; } } ``` 另外,如果需要在遍历过程中修改字典的成员,可以考虑使用一个临时列表来存储需要修改的键,然后再根据临时列表来修改字典。这样可以避免在遍历过程中修改字典导致的问题。\[3\] #### 引用[.reference_title] - *1* *2* [c#遍历字典并删除元素](https://blog.csdn.net/realfancy/article/details/113103622)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [c# 遍历字典改key](https://blog.csdn.net/luoyikun/article/details/78787686)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值