实例化反映的委托类型

时间:2019-07-15 10:16:13

标签: c# lambda reflection

我有一个类型变量

Code to Encrypt
public void FileEncrypt(string inputFile, string password)
{
//create output file name
FileStream fsCrypt = new FileStream(@"PathToSaveEncryptedFileTo", FileMode.Create);

    //generate random salt of 32 bytes
    byte[] salt = GenerateRandomSalt();
    //convert password string to byte arrray
    byte[] passwordBytes = Convert.FromBase64String(password);

    //Set Rijndael symmetric Encryption algorithm
    AesManaged AES = new AesManaged();
    AES.KeySize = 256;
    AES.BlockSize = 128;
    AES.Padding = PaddingMode.PKCS7;
    var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
    AES.Key = key.GetBytes(AES.KeySize / 8);
    AES.IV = key.GetBytes(AES.BlockSize / 8);
    AES.Mode = CipherMode.CBC;

    // write salt to the begining of the output file
    fsCrypt.Write(salt, 0, salt.Length);

    CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write);


    FileStream fsIn = new FileStream(inputFile, FileMode.Open);

    byte[] wholeFile = new byte[fsIn.Length];
    fsIn.Read(wholeFile, 0, wholeFile.Length);

    fsCrypt.Close();


    //create a buffer (1mb) so only this amount will allocate in the memory and not the whole file
    byte[] buffer = new byte[1048576];
    int read;

    try
    {
        while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
        {
            Application.DoEvents();
            cs.Write(buffer, 0, read);
        }
 cs.FlushFinalBlock();
       // Close up
       fsIn.Close();
    }
}

现在,我检查 Code to Decrypt public void FileDecrypt(string encryptedFile, string outputFile, string password) { byte[] passwordBytes = Convert.FromBase64String(password); byte[] salt = new byte[32]; FileStream fsCrypt = new FileStream(encryptedFile, FileMode.Open); fsCrypt.Read(salt, 0, salt.Length); AesManaged AES = new AesManaged(); AES.KeySize = 256; AES.BlockSize = 128; var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Padding = PaddingMode.PKCS7; AES.Mode = CipherMode.CBC; CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read); FileStream fsOut = new FileStream(outputFile, FileMode.Create); int read; byte[] buffer = new byte[1048576]; try { while ((read = cs.Read(buffer, 0, buffer.Length)) > 0) { Application.DoEvents(); fsOut.Write(buffer, 0, read); } } catch (CryptographicException ex_CryptographicException) { Console.WriteLine("CryptographicException error: " + ex_CryptographicException.Message); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } try { cs.Close(); } catch (Exception ex) { Console.WriteLine("Error by closing CryptoStream: " + ex.Message); } finally { fsOut.Close(); fsCrypt.Close(); } } 是否遵循约定,

using System;
using System.Linq;
using System.Reflection;

...

var validateFuncType = typeof(Func<,>).MakeGenericType(someVariableType, typeof(bool));

然后根据支票

someVariableType

实例化委托类型的实例。

您能帮我吗,如何实例化调用常规实现的var validateOfType = someVariableType .GetMethods(BindingFlags.Instance | BindingFlags.Public) .SingleOrDefault(mi => { if (mi.Name != "Validate" || mi.ReturnType != typeof(bool)) { return false; } var parameters = mi.GetParameters(); return parameters.Length == 0; }); (如果存在)?

3 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您正在寻找Delegate.CreateDelegate

var alwaysReturnTrueMethodInfo = typeof(YourClass).GetMethod("AlwaysReturnTrue").MakeGenericMethod(someVariableType);
Delegate validateFunc;
if (validateOfType == null)
{
    validateFunc = Delegate.CreateDelegate(validateFuncType, alwaysReturnTrueMethodInfo);
}
else
{
    validateFunc = Delegate.CreateDelegate(validateFuncType, validateOfType);
}

其中AlwaysReturnTrue是这样声明的辅助静态方法:

public static bool AlwaysReturnTrue<T>(T t) { return true }

答案 1 :(得分:0)

您可以通过以下方式进行操作:

// create an object of the type
var obj = Activator.CreateInstance(validateFuncType);

然后您将在obj中获得validateFuncType的实例。

另一种方法是使用反射:

// get public constructors
var ctors = validateFuncType.GetConstructors(BindingFlags.Public);

// invoke the first public constructor with no parameters.
var obj = ctors[0].Invoke(new object[] { });

此内容取自this SO answer。因此,这个问题(和答案)可能被标记为重复。

答案 2 :(得分:0)

在注意到Func<>的输入参数是互变量之后,我做了什么。

object validateFunc = validateOfType != null
                ? config => (bool)validateOfType.Invoke(config, new object[0])
                : new Func<object, bool>(_ => true);

我不确定这是否比@Sweeper's answer