【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:\test.snk 
3、输入sn -p c:\test.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:\test.snk 创建一个新的随机密钥对并将其存储在 c:\test.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:\test.snk文件中保存的公钥。那怎么才能看到这个公钥了,照样是用SN.EXE。
输入sn -p c:\test.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

转载于:https://www.cnblogs.com/LiveYourLife/p/9681982.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
联合体(Union)是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。在 C# 中,我们可以使用结构体和枚举类型来模拟联合体的功能。在本文中,我们将介绍如何在 C# 中使用结构体和枚举类型实现联合体。 1. 使用结构体模拟联合体 结构体(Struct)是一种用户定义的类型,它允许将不同类型的数据组合在一起。在 C# 中,我们可以使用结构体来模拟联合体的功能。下面是一个示例: ``` struct Union { public int intValue; public float floatValue; } ``` 在上面的代码中,我们定义了一个结构体 Union,它包含两个成员变量:intValue 和 floatValue。在使用时,我们可以根据需要设置其中一个成员变量并读取它的值,例如: ``` Union union = new Union(); union.intValue = 10; Console.WriteLine(union.floatValue); ``` 在上面的代码中,我们设置了 intValue 的值为 10,然后读取 floatValue 的值。由于它们在内存中使用了相同的位置,因此 floatValue 的值将是不确定的。 2. 使用枚举类型模拟联合体 枚举类型(Enum)是一种用户定义的类型,它允许将一组命名常量定义为一个类型。在 C# 中,我们可以使用枚举类型来模拟联合体的功能。下面是一个示例: ``` enum Union { IntValue, FloatValue } ``` 在上面的代码中,我们定义了一个枚举类型 Union,它包含两个常量:IntValue 和 FloatValue。在使用时,我们可以根据需要设置其中一个常量并读取它的值,例如: ``` Union union = Union.IntValue; int value = (int)union; Console.WriteLine(value); ``` 在上面的代码中,我们设置了 union 的值为 IntValue,然后将其转换为整数类型并输出。由于 IntValue 和 FloatValue 在内存中使用了相同的位置,因此我们也可以将 union 的值设置为 FloatValue,并读取它的值。 总结 在 C# 中,我们可以使用结构体和枚举类型来模拟联合体的功能。虽然这种方式不如使用 C 或 C++ 中的联合体方便,但是它仍然可以满足一些特定的需求。在使用时,我们需要注意内存位置的问题,以避免出现不确定的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值