Switch 内 case 语句中的非静态/常量值

发布于 2024-12-27 21:03:48 字数 648 浏览 2 评论 0原文

我想在 C# 中的 switch 语句中评估动态 string 值。

例如:

int i = 0;
foreach (Item item in _Items)
{
    foreach (Field theField in doc.Form.Fields)
    {
        switch (theField.Name)
        {
            case "Num" + i++.ToString(): // Dynamic Evaluation?
                theField.Value = string.Empty;
                break;
        }
    }
}

我有 20 个左右的字段,名为 Num1Num2 等。如果我可以在一个语句/块中完成所有这些操作,我更愿意这样做。

但编译器抱怨 case 语句需要是常量值。有没有办法在 case 语句中使用动态变量,这样我就可以避免重复代码?

我只是想提一下,此方法的目的是使用我无法控制的命名约定填充 PDF 表单中的字段。有 20 行字段,名称如“Num1”-“Num20”。这就是为什么字符串连接在我的场景中会很有帮助。

I would like to evaluate a dynamic string value within a switch statement in C#.

For example:

int i = 0;
foreach (Item item in _Items)
{
    foreach (Field theField in doc.Form.Fields)
    {
        switch (theField.Name)
        {
            case "Num" + i++.ToString(): // Dynamic Evaluation?
                theField.Value = string.Empty;
                break;
        }
    }
}

I have 20 or so fields named Num1, Num2, etc. If I can do this all in one statement/block, I'd prefer to do so.

But the compiler complains that the case statements need to be constant values. Is there a way to use dynamic variables in the case statement so I can avoid repeating code?

I just thought I'd mention, the purpose of this method is to populate the fields in PDF form, with naming conventions which I can not control. There are 20 rows of fields, with names like "Num1" - "Num20". This is why string concatenation would be helpful in my scenario.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

唔猫 2025-01-03 21:03:49
var matchingFields =
    from item in _Items
    join field in doc.Form.Fields
      on "Num" + item.PackageCount equals field.Name
    select field;

foreach (var field in matchingFields)
{
    field.Value = string.Empty;
}

为了提高效率,在获取匹配字段后,在字段名称上添加 DistinctBy(来自 MoreLINQ 或同等字段) 。

var matchingFields =
    from item in _Items
    join field in doc.Form.Fields
      on "Num" + item.PackageCount equals field.Name
    select field;

foreach (var field in matchingFields)
{
    field.Value = string.Empty;
}

For more efficiency include a DistinctBy on field Name after getting the matching fields (from MoreLINQ or equivalent).

朦胧时间 2025-01-03 21:03:49

还要考虑到每次将两个或多个字符串连接在一起时,编译器都会为每个组成字符串创建内存变量,然后为最终字符串创建另一个内存变量。这是内存密集型的,对于像错误报告这样的非常大的字符串,它甚至可能是一个性能问题,并且对于长时间运行的程序来说,还可能导致运行的程序中出现内存碎片。在这种情况下可能没有那么多,但是将这些最佳实践发展到您通常的开发例程中是很好的。

因此,不要这样写:

"Num" + i++.ToString()

考虑这样写:

string.Format("{0}{1}", "Num", i++.ToString());

另外,您可能需要考虑将像“Num”这样的字符串放入单独的常量类中。随着程序的增长,代码中包含字符串常量可能会导致程序僵化,并限制程序的灵活性。

所以你的程序开头可能有这样的东西:

using SysConst = MyNamespace.Constants.SystemConstants;

然后你的代码看起来像这样:

string.Format("{0}{1}", SysConst.Num, i++.ToString());

在你的 SystemConstants 类中,你会有这样的东西:

/// <summary>System Constants</summary>
public static class SystemConstants
{
    /// <summary>The Num string.</summary>
    public static readonly string Num = @"Num";
}

这样,如果你需要在任何地方使用“Num”字符串否则,在您的程序中,您可以只使用“SysConst.Num”

此外,任何时候您决定将“Num”更改为“Number”,例如根据客户请求,那么您只需在一处更改它,而且不是一个大的在您的系统中查找-替换。

Also consider that every time you concatenate two or more strings together the compiler will create memory variables for each of the component strings and then another one for the final string. This is memory intensive and for very large strings like error reporting it can even be a performance problem, and can also lead to memory fragmentation within your programs running, for long-running programs. Perhaps not so much in this case, but it is good to develop those best-practices into your usual development routines.

So instead of writing like this:

"Num" + i++.ToString()

Consider writing like this:

string.Format("{0}{1}", "Num", i++.ToString());

Also you may want to consider putting strings like "Num" into a separate constants class. Having string constants in your code can lead to program rigidity, and limit program flexibility over time as your program grows.

So you might have something like this at the beginning of your program:

using SysConst = MyNamespace.Constants.SystemConstants;

Then your code would look like this:

string.Format("{0}{1}", SysConst.Num, i++.ToString());

And in your SystemConstants class, you'd have something like this:

/// <summary>System Constants</summary>
public static class SystemConstants
{
    /// <summary>The Num string.</summary>
    public static readonly string Num = @"Num";
}

That way if you need to use the "Num" string any place else in your program, then you can just use the 'SysConst.Num'

Furthermore, any time you decide to change "Num" to "Number", say perhaps per a customer request, then you only need to change it in one place, and not a big find-replace in your system.

鲸落 2025-01-03 21:03:48

不,这只是语言的一部分。如果值不是常量,则必须使用 if/else if 或类似的解决方案。 (如果我们知道有关您想要实现的目标的更多详细信息,我们也许能够提供解决方案的更多详细信息。)

从根本上讲,我会质疑具有此类字段命名约定的设计 - 听起来真的您应该从一个集合开始,这更容易使用。

No. This is simply part of the language. If the values aren't constants, you'll have to use if/else if or a similar solution. (If we knew more details about what you were trying to achieve, we may be able to give more details of the solution.)

Fundamentally, I'd question a design which has a naming convention for the fields like this - it sounds like really you should have a collection to start with, which is considerably easier to work with.

毁梦 2025-01-03 21:03:48

是的,case 值必须能够在编译时进行评估。换成这个怎么样

foreach (Field theField in doc.Form.Fields)
{
    if(theField.Name == ("Num" + i++))
    {
        theField.Value = string.Empty;
    }
}

Yes case value must be able to be evaluated at compile time. How about this instead

foreach (Field theField in doc.Form.Fields)
{
    if(theField.Name == ("Num" + i++))
    {
        theField.Value = string.Empty;
    }
}
娜些时光,永不杰束 2025-01-03 21:03:48

怎么样:

int i = 0;
foreach ( Item item in _Items )
    doc.Form.Fields.First(f=>f.Name == "Num" + i++.ToString()).Value = string.Empty;

但不确定代码中 item 的用途是什么。

How about:

int i = 0;
foreach ( Item item in _Items )
    doc.Form.Fields.First(f=>f.Name == "Num" + i++.ToString()).Value = string.Empty;

Not sure what the purpose of item is in your code though.

流云如水 2025-01-03 21:03:48

不,没有办法。

将开关替换为:

if (theField.Name.StartsWith("Num"))
  theField.Value = string.Empty;

或类似的测试怎么样?

No. There is no way.

How about replacing the switch with:

if (theField.Name.StartsWith("Num"))
  theField.Value = string.Empty;

or some similar test?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文