一般每一个程序都有大量的资源。对于这些图片资源的存放一般有三种方法:
1. 将这些资源一个一个专门放在一个文件夹中,程序调用的时候直接根据文件名读取文件夹里的图片即可
2. 将这些资源分别放在各个子程序的程序集中,运行时直接通过资源文件的调用即可
3. 将这些资源专门整合在一个文件中,如dll文件,运行时通过dll调用来获得相应的资源即可
第一种方法方便明了但不利于图片的保护,第二种方法虽然保护好图片了,但是可能会造成重复的文件重复存放,所以感觉第三种方法方便实惠也利于保护。
然而,采用了第三种方法后,问题又来了,如何获得所需要的资源呢?通常如果资源存放在同一程序集的资源文件中的话可以直接使用
global::<namespace>.Properties.<资源文件类名>.资源名
来获取,返回的类型根据资源类型的不同而不同。但是当前情况是另一个程序来调用资源文件,而传入的参数一般都是文件名,从而获取同文件名的资源,那又该怎么实现这个功能呢?总不至于通过几十个case来一个一个判断吧,劳心劳力,一不小心还会出错,吃力不讨好。
其实,.Net强大的反射机制能够帮助我们自动完成所需要的这个功能——
System.Reflection.Assembly类中有两个重要的方法:GetManifestResourceNames和GetManifestResourceStream,看名字大家都应该很清楚了,前者是获得程序集中所有资源的名字,而后者则是获得资源的流。有了这两样,还愁得不到所需要的资源么?呵呵,别急,在这之前还有一步:那就是将所导入的资源的Build Action属性改成Embedded Resource(嵌入的资源),这样GetManifestResourceNames才能够获得这些资源的名称。
最后,是实现的代码,不管你有多少图片,这段代码都能搞定(这段代码中的imageName是不带扩展名的)
public
System.Drawing.Bitmap GetImage(
string
imageName)
...
{
System.Drawing.Bitmap requestPic = null;
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resNames = assembly.GetManifestResourceNames();
foreach (string aResName in resNames)
...{
string[] resNameSplit = aResName.Split('.');
if (resNameSplit[resNameSplit.Length - 2] == imageName)
...{
Stream aResStream = assembly.GetManifestResourceStream(aResName);
requestPic = new System.Drawing.Bitmap(aResStream);
break;
}
}
return requestPic;
}