为局部变量定义动态计算公式
define a dynamically-evaluated formula for a local variable
我正在查看一段错误处理代码,如下所示:
if (condition) {
thereIsAProblem = true;
problemDescription = "x";
}
if (!thereIsAProblem && condition2) {
thereIsAProblem = true;
problemDescription = "y";
}
我想知道是否有一种方法可以定义一个名为 thereIsNotAProblem
的局部变量,该变量动态地基于 thereIsAProblem
的值。换句话说:
var thereIsAProblem = false;
var thereIsNotAProblem = *** some expression... ***
Console.WriteLine(thereIsNotAProblem); // true
thereIsAProblem = true;
Console.WriteLine(thereIsNotAProblem); // false
if (thereIsNotAProblem && condition3) {
..
}
是否可以在上面的行中输入一些表达式,将 thereIsNotAProblem
的值指定为基于 !thereIsAProblem
的动态公式,并且仍然允许 thereIsNotAProblem
在任何需要 bool
值的地方提供?
不太...但您可以改为将其设为委托:
Func<bool> thereIsNotAProblem = () => { /* some expression */ };
Console.WriteLine(thereIsNotAProblem()); // true
thereIsAProblem = true;
Console.WriteLine(thereIsNotAProblem()); // false
请注意现在每次我们想要评估 thereIsNotAProblem
我们调用委托...它评估表达式以获得 bool
值。
虽然您可以通过声明 lambda 来做到这一点,
var thereIsAProblem = false;
Func<bool> thereIsNotAProblem = () => !thereIsAProblem;
我认为你不应该这样做。 thereIsAProblem
和 thereIsNotAProblem
看起来非常相似,因此很容易将一个误读为另一个。使用 !
来否定具有正名称的变量是很好理解和易于阅读的,应该会导致更少的错误。
我进一步认为,更好的解决方案是 "fail fast" 出现问题后立即返回的方法,避免了首先测试早期问题的需要:
if (condition)
{
problemDescription = "x";
return;
}
if (condition2)
{
problemDescription = "y";
return;
}
...
您可以使用以下方法
(另见 .NET Fiddle https://dotnetfiddle.net/E9X6XJ )
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("YourQuestion() returns " + YourQuestion());
Console.WriteLine("AnswerOne() returns " + AnswerOne());
Console.WriteLine("AnswerTwo() returns " + AnswerTwo());
}
private static bool condition1()
{
return false;
}
private static bool condition2()
{
return true;
}
private static bool condition3()
{
return true;
}
public static string YourQuestion()
{
var thereIsAProblem = false;
var problemDescription = "";
if (condition1()) {
thereIsAProblem = true;
problemDescription = "x";
}
if (!thereIsAProblem && condition2()) {
thereIsAProblem = true;
problemDescription = "y";
}
return problemDescription;
}
public static string AnswerOne()
{
return checkCondition1() ??
checkCondition2() ??
checkCondition3();
}
private static string checkCondition1()
{
return condition1() ? "x" : null;
}
private static string checkCondition2()
{
return condition2() ? "y" : null;
}
private static string checkCondition3()
{
return condition3() ? "z" : null;
}
public static string AnswerTwo()
{
var conditionChecks = new Dictionary<string,Func<bool>>();
conditionChecks.Add("x",condition1);
conditionChecks.Add("y",condition2);
conditionChecks.Add("z",condition3);
foreach (var check in conditionChecks)
{
if (check.Value())
{
return check.Key;
}
}
return null;
}
}
我正在查看一段错误处理代码,如下所示:
if (condition) {
thereIsAProblem = true;
problemDescription = "x";
}
if (!thereIsAProblem && condition2) {
thereIsAProblem = true;
problemDescription = "y";
}
我想知道是否有一种方法可以定义一个名为 thereIsNotAProblem
的局部变量,该变量动态地基于 thereIsAProblem
的值。换句话说:
var thereIsAProblem = false;
var thereIsNotAProblem = *** some expression... ***
Console.WriteLine(thereIsNotAProblem); // true
thereIsAProblem = true;
Console.WriteLine(thereIsNotAProblem); // false
if (thereIsNotAProblem && condition3) {
..
}
是否可以在上面的行中输入一些表达式,将 thereIsNotAProblem
的值指定为基于 !thereIsAProblem
的动态公式,并且仍然允许 thereIsNotAProblem
在任何需要 bool
值的地方提供?
不太...但您可以改为将其设为委托:
Func<bool> thereIsNotAProblem = () => { /* some expression */ };
Console.WriteLine(thereIsNotAProblem()); // true
thereIsAProblem = true;
Console.WriteLine(thereIsNotAProblem()); // false
请注意现在每次我们想要评估 thereIsNotAProblem
我们调用委托...它评估表达式以获得 bool
值。
虽然您可以通过声明 lambda 来做到这一点,
var thereIsAProblem = false;
Func<bool> thereIsNotAProblem = () => !thereIsAProblem;
我认为你不应该这样做。 thereIsAProblem
和 thereIsNotAProblem
看起来非常相似,因此很容易将一个误读为另一个。使用 !
来否定具有正名称的变量是很好理解和易于阅读的,应该会导致更少的错误。
我进一步认为,更好的解决方案是 "fail fast" 出现问题后立即返回的方法,避免了首先测试早期问题的需要:
if (condition)
{
problemDescription = "x";
return;
}
if (condition2)
{
problemDescription = "y";
return;
}
...
您可以使用以下方法 (另见 .NET Fiddle https://dotnetfiddle.net/E9X6XJ )
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("YourQuestion() returns " + YourQuestion());
Console.WriteLine("AnswerOne() returns " + AnswerOne());
Console.WriteLine("AnswerTwo() returns " + AnswerTwo());
}
private static bool condition1()
{
return false;
}
private static bool condition2()
{
return true;
}
private static bool condition3()
{
return true;
}
public static string YourQuestion()
{
var thereIsAProblem = false;
var problemDescription = "";
if (condition1()) {
thereIsAProblem = true;
problemDescription = "x";
}
if (!thereIsAProblem && condition2()) {
thereIsAProblem = true;
problemDescription = "y";
}
return problemDescription;
}
public static string AnswerOne()
{
return checkCondition1() ??
checkCondition2() ??
checkCondition3();
}
private static string checkCondition1()
{
return condition1() ? "x" : null;
}
private static string checkCondition2()
{
return condition2() ? "y" : null;
}
private static string checkCondition3()
{
return condition3() ? "z" : null;
}
public static string AnswerTwo()
{
var conditionChecks = new Dictionary<string,Func<bool>>();
conditionChecks.Add("x",condition1);
conditionChecks.Add("y",condition2);
conditionChecks.Add("z",condition3);
foreach (var check in conditionChecks)
{
if (check.Value())
{
return check.Key;
}
}
return null;
}
}