我的代码看起来很难看,而且我知道必须有更好的方法来做我正在做的事情:
private delegate string doStuff(
PasswordEncrypter encrypter, RSAPublicKey publicKey,
string privateKey, out string salt
);
private bool tryEncryptPassword(
doStuff encryptPassword,
out string errorMessage
)
{
...get some variables...
string encryptedPassword = encryptPassword(encrypter, publicKey,
privateKey, out salt);
...
}
到目前为止这个东西并没有打扰我。这就是我调用tryEncryptPassword
看起来如此丑陋,并且有重复的原因,因为我用两种方法调用它:
public bool method1(out string errorMessage)
{
string rawPassword = "foo";
return tryEncryptPassword(
(PasswordEncrypter encrypter, RSAPublicKey publicKey,
string privateKey, out string salt) =>
encrypter.EncryptPasswordAndDoStuff( // Overload 1
rawPassword, publicKey, privateKey, out salt
),
out errorMessage
);
}
public bool method2(SecureString unencryptedPassword,
out string errorMessage)
{
return tryEncryptPassword(
(PasswordEncrypter encrypter, RSAPublicKey publicKey,
string privateKey, out string salt) =>
encrypter.EncryptPasswordAndDoStuff( // Overload 2
unencryptedPassword, publicKey, privateKey, out salt
),
out errorMessage
);
}
丑陋的两个部分:
out
参数,我必须明确列出lambda表达式中的所有参数类型。EncryptPasswordAndDoStuff
的两个重载除了第一个参数(可以是string
或SecureString
之外)采用所有相同的参数。因此method1
和method2
几乎完全相同,只是调用EncryptPasswordAndDoStuff
的不同重载。有什么建议吗?
编辑(解决方案):我最终使用了Jeff的建议并更改了EncryptPasswordAndDoStuff
的重载以返回EncryptionResult
的实例。然后我不需要明确定义delegate
,我使用了以下代码:
private bool tryEncryptPassword(KeysAndEncrypter keys,
Func<EncryptionResult> encryptPassword,
out string errorMessage
) { ... }
private class KeysAndEncrypter
{
public RSAPublicKey PublicKey { get; set; }
public string PrivateKey { get; set; }
public PasswordEncrypter Encrypter { get; set; }
}
以下是method1
的内容,其中method2
非常相似:
string rawPassword = "foo";
KeysAndEncrypter keys = getEncryptionKeys();
return tryEncryptPassword(keys, () =>
keys.Encrypter.EncryptPasswordAndDoStuff(
rawPassword, keys.PublicKey, keys.PrivateKey
),
out errorMessage
);
答案 0 :(得分:5)
您可以引入一种新类型来表示委托的返回值:
public class EncryptionResult {
public string EncryptedValue { get; set; }
public string Salt { get; set; }
}
...并将委托更改为以下内容:
private delegate EncryptionResult doStuff(
PasswordEncrypter encrypter,
RSAPublicKey publicKey,
string privateKey);
答案 1 :(得分:2)
为什么要打扰疯狂的lambda呢?
public bool Method1(out string errorMessage)
{
return TryEncryptPassword("foo", out errorMessage);
}
public bool Method2(SecureString password, out string errorMessage)
{
return TryEncryptPassword(password, out errorMessage);
}
private bool TryEncryptPassword(string password, out string errorMessage)
{
GetSomeVariables();
string encryptedPassword = encrypter.EncryptPasswordAndDoStuff(
password, publicKey, privateKey, out salt);
DoMoreStuff();
// ...
}
private bool TryEncryptPassword(SecureString password, out string errorMessage)
{
GetSomeVariables();
string encryptedPassword = encrypter.EncryptPasswordAndDoStuff(
password, publicKey, privateKey, out salt);
DoMoreStuff();
// ...
}
private void GetSomeVariables() { /* ...get some variables... */ }
private void DoMoreStuff() { /* ... */ }
答案 2 :(得分:1)
杰夫的建议是合理的。如果您不想在每次需要out参数时都定义新类型,也可以使用Tuple<string, string>
。
另一个建议是传入另一个委托来检索错误,而不是使用out参数。
private bool tryEncryptPassword(
doStuff encryptPassword,
Action<string> setError
)
public bool method1(Action<string> setError) {
...
tryEncryptPassword(..., ..., ..., setError);
}
在调用method1之前,可以将setError分配给局部变量。
string error;
Action<string> setError = str => error = str;
method1(setError);
答案 3 :(得分:0)
此外,如果您不想创建自定义类型,则可以在此处返回元组。
private delegate Tuple<string, string> doStuff(
PasswordEncrypter encrypter,
RSAPublicKey publicKey,
string privateKey);
在doStuff中,只需创建并返回一个元组:
Tuple<string, string> result = new Tuple<string, string>(EncryptedValue, Salt);
return result;