传递没有构造函数的类型作为参数

本文关键字:类型 参数 构造函数 | 更新日期: 2023-09-27 18:03:04

我一直在使用不同的System.Security.Cryptography哈希函数,以了解不同哈希系统的键长度。为此,我考虑编写一个基于参数返回键大小的方法。(返回密钥大小不是问题,这就是我问这个问题的原因)

I thought about this:

// I know I could use the interface as the type of T but let's define it as dynamic for now 
public static Byte[] Size(dynamic T) {
    return T.Create().ComputeHash(Encoding.Default.GetBytes("hello"));
}

现在,因为这些哈希函数(哈希生成类型)没有构造函数,所以我不能像

那样使用这个方法
 Size(new MD5()); // This is wrong coz there is no constructor

不能像

那样传递类型
Size(MD5); // Error 

如果我想直接传递这些类型作为参数,而不首先声明它们并像MD5 md5Size(md5)一样传递它们,我到底要做什么?我只是好奇这是否可能。

传递没有构造函数的类型作为参数

可以通过反射来实现

var size = Size<MD5>();

public static Byte[] Size<T>()
{
    dynamic hashFxn = typeof(T).InvokeMember("Create",BindingFlags.Static| BindingFlags.Public | BindingFlags.InvokeMethod,null,null,null);
    return hashFxn.ComputeHash(Encoding.Default.GetBytes("hello"));
}

不能直接创建MD5类的实例,因为它被标记为抽象。相反,您应该创建继承MD5的类的实例。

System.Security.Cryptography中有两个选项,MD5CngMD5CryptoServiceProvider

现在,您可以通过Size(new MD5CryptoServiceProvider()),但它将在运行时失败,因为MD5MD5CryptoServiceProvider没有暴露实例Create方法。

修改你的方法以HashAlgorithm代替dynamic,并删除Create方法调用:

public static Byte[] Size(HashAlgorithm T) {
    return T.ComputeHash(Encoding.Default.GetBytes("hello"));
}

MD5是一个抽象类,所以您需要提供一个具体的子类。你可以这样做:

public static byte[] Size<T>() where T : HashAlgorithm, new()
{
    using (var hash = new T())
    {
        return hash.ComputeHash(Encoding.Default.GetBytes("hello"));
    }
}

,像这样使用

var bytes = Size<MD5CryptoServiceProvider>();