• 【c#技术】一篇文章搞掂:常见C#技术问题


    1、事件作为参数传递

    public class Para
    {
        // 定义一种委托(事件类型),可以在此定义这个事件的返回值和参数
        public delegate object GetDataMethodAction();
        // 使用这个事件类型接收参数
        public GetDataMethodAction GetDataMethod { get; set; }
    }
    
    public void Main()
    {
        // 构建事件参数
        Para para = new Para(){
            GetDataMethod = () => { return new InvStorageManager().selectForApp().data; }
        };
        // 传入参数
        test(para);
    }
    
    public void test(Para para)
    {
        // 调用传入的事件
        var result = para.GetDataMethod.Invoke();
    }

    2、反射

    //一、从程序集反射所有类
    Type[] typeArr = Assembly.LoadFrom("Ciphis.BusinessLogic.dll").GetTypes();//程序集
    foreach (Type t in typeArr)
    {
        if (t.ToString() == "Ciphis.HelperClasses.SalesOrderFields")//命名控件+类名
        {
    
        }
    }
    
    //二、获取某个类的属性值和属性名称
    //获取所有属性
    System.Reflection.PropertyInfo[] properties = t.GetProperties();
    foreach (System.Reflection.PropertyInfo property in properties)
    {
        string name = property.Name;
        object value = property.GetValue(null,null);//第一个参数可以传入某个实体?如果获取静态类的值好像可以传入null
    }

    3、类库的开放性,针对某些程序集开放某些类、方法

    可以设置类A为Internal
    然后在该类库的AssemblyInfo.cs中
    写[assembly:InternalsVisibleTo("UnitTest")],对某个类库开放
    
    创建签名
    1、打开VS命令提示行
    开始 -- 程序 -- Microsoft Visual Studio 2005 -- Visual Studio Tools --Visual Studio 2005 命令提示
    2、输入sn -k c:	est.snk 
    3、输入sn -p c:	est.snk c:publicKey.snk 生成公钥
    4、输入sn -tp c:publicKey.snk 显示公钥
    
    在加密类库写
    [assembly: InternalsVisibleTo("LTMain,PublicKey=002400000480000094000000060200000024000052534131000400000100010097b16f9cfea93610a1726634cb6427e185590dbc752aec69025c28fd9638f8c078126414bf9d112324f7132f960262785bf77525f92522cb7db726c2c087b19ec7623169b8958babaff76959d186311fbc20764a2eb2a0cbd187c7f53452b05007f8d1c941830c4dc73e80d2ecf32bdb6f0a78d07f79bbbc2afc10117e5714ba")]
    然后把test.snk复制到LTMain项目中,在LTMain项目属性中设置签名为text.snk
    这样LTMain就可以引用加密类库中的Internal类
    
    如果出现错误,全部类库都加上这个签名肯定没错的
    
    
    http://www.west.cn/www/info/60919-1.htm
    大家做项目开发一般都是分层的,比如UI层,业务层,数据访问层。业务层引用数据访问层的DLL(比如dataAccess.dll),并使用dataAccess.dll中的方法。当项目完成并给客户用了,可有些心里BT的客户这个时候也可以请个稍微懂NET的人来引用你的dataAccess.dll并调用其中的方法搞破坏。比如可以直接使用里面的ChangePwd(string UserName,string Pwd)方法把其他用户的密码改了,这个时候就你就.......
    好了,该开始说怎么保护我们的代码了:
    首先我们需要把我们的程序集做成强命名的程序集。
    这里我们在.NET 命令提示中输入sn -k c:	est.snk 创建一个新的随机密钥对并将其存储在 c:	est.snk 中
    然后新建立类库ClassLibrary1,里面只有个类文件Class1.cs,代码如下:
    using System;
    
    namespace ClassLibrary1
    {
    public class Class1
    {
    public Class1()
    {
    //
    // TODO: 在此处添加构造函数逻辑
    //
    }
    
    public string Insert()
    {
    return "ok";
    }
    }
    }
    
    AssemblyInfo.cs代码:
    //............其他的就用默认
    [assembly: AssemblyKeyFile("c:\test.snk")] // 连接上面用强命名工具SN.exe生成的文件.
    
    接着创建个WindowApplication来调用我们的ClassLibrary1,代码:
    private void button1_Click(object sender, System.EventArgs e)
    {
    MessageBox.Show(new ClassLibrary1.Class1().Insert());
    }
    不修改WindowApplication的AssemblyInfo.cs。
    在这里就可以直接运行了,不过大家都看的出来,这样是能成功调用Class1中的方法的。
    
    现在让我们来修改下Class1.cs,代码:
    using System;
    using System.Security.Permissions;
    namespace ClassLibrary1
    {
    [StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = 
    "00240000048000009400000006020000002400005253413100040000010001000551684edd1600"+
    "8ccbdd337b1cf1490490d97fe0048c5f3629cc4f5104578499eace9b2a94115022edd620def472"+
    "8b4f088291cfa77a40659afba611fdafbb7894b93a64049d439936bd0cd8dc0704625aeb735892"+
    "e9eb3f910a49a2925af10515d935654d7adac5567ff6d780d23d587de0ff4d271da7b30680fa88"+
    "a47a4ba4")]
    public class Class1
    {
    public Class1()
    {
    //
    // TODO: 在此处添加构造函数逻辑
    //
    }
    
    public string Insert()
    {
    return "ok";
    }
    }
    }
    
    然后再编译后运行windowapplication调用class1中的方法就会出错。
    这里的StrongNameIdentityPermissionAttribute是NET提供的CAS(Code Access Security)中的1个类,具体可参考MSDN,SecurityAction.LinkDemand 是要求直接调用方已被授予了指定的权限,这里即windowapplication要授予了权限才行,如果使用SecurityAction.Demand要求调用堆栈中的所有高级调用方都已被授予了当前权限对象所指定的权限。他们的区别是:如果windowapplication已授权访问,而还有个windowapplication2(未授权访问)通过调用windowapplication中的button1_Click方法来调用class1,这个时候如果使用SecurityAction.LinkDemand就能成功调用,而使用SecurityAction.Demand windowapplication2就不能调用,windowapplication 在这2种情况下都能调用。
    说到这里大家一定再问PublicKey=后面一串那么长的字符串怎么来。PublicKey后面的字符串是你开始生成的c:	est.snk文件中保存的公钥。那怎么才能看到这个公钥了,照样是用SN.EXE。
    输入sn -p c:	est.snk c:publicKey.snk (从 test.snk 中提取公钥并将其存储在 publicKey.snk 中)
    再输入sn -tp c:publicKey.snk (显示公钥信息)
    上面这个命令就能看到PublicKey后面的字符串了,还想什么啊,把那字符串copy下来啊。
    最后大家一定在关心这个时候windowapplication 要怎么调用class1了,其实也简单,只要把windowapplication 的AssemblyInfo.cs修改为:
    [assembly: AssemblyKeyFile("c:\test.snk")]
    到这里就一切OK了,大家都看到最关键的就是test.snk文件了,所以一定要保护好你自己的test.snk文件。
    下面是我的代码,大家可以下载看看,在使用的时候记的要把我KEY文件夹下的test.snk copy到c盘。
    不然会出错^_^。
    http://www.cnblogs.com/Files/BearsTaR/Solution1.rar
    View Code

    4、程序内存超过1.2G报错退出

    因为软件设置了X86平台,应该改成anyCPU

  • 相关阅读:
    [HIS] HIT行业常用名词及缩写定义
    String Split 和 Join
    深入解析字符串的比较方法:“==”操作符;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。
    Oracle安装时先决条件检查失败的解决方案
    C#创建XML文件并保存
    关于SQL Server 数据库的备份
    为Windows 7添加“Internet打印”功能
    C#如何使用和开发自定义配置节
    C#中配置文件的使用
    键盘KeyCode值列表
  • 原文地址:https://www.cnblogs.com/LiveYourLife/p/9681982.html
Copyright © 2020-2023  润新知