C# 将 VBA For Each 循环转换为 C# 但给出编译错误

C# converting a VBA For Each loop to C# but gives compile error

我正在将 Word VBA 宏转换为 C# 中的插件。

到目前为止,我已经成功重构了 C# 中的所有语句、方法和属性,但是这个让我很难过:

For Each l In Application.Languages
    If InStr(LCase(l.NameLocal), LCase(Language)) > 0 Then
        Selection.LanguageID = l.ID
        Exit For
    End If
Next l

我将上面的内容用C#转换如下:

using Microsoft.Office;
using Microsoft.Office.Interop;
using Word = Microsoft.Office.Interop.Word;

Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();
var Selection = oWordDoc.ActiveWindow.Selection;
string strTgtLanguage = "Hungarian";

foreach (var item in oWord.Application.Languages)
{
          if (item.NameLocal.IndexOf(strTgtLanguage)>-1) 
//The error is  ---^  here on 'NameLocal'.
          {
              Selection.LanguageID = item.ID
//And here on 'ID' -----------------------^
              break;
          }
}

两个实例的编译器错误是:

'object' does not contain a definition for 'NameLocal' and no extension method 'NameLocal' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

我在这里做错了什么?我认为 foreach 语句正确地声明了集合中的 object

提前致谢。

对于您的错误代码,第一个错误在我看来是您的 oWord.Application.Languages 实际上 return 不是一个名为 NameLocal.

的集合字段

第二个Selection.LanguageID = l.ID应该是Selection.LanguageID = item.ID

var item 替换为类型名称。

foreach (var item in oWord.Application.Languages) 替换为 foreach (Word.Language item in oWord.Languages)

var 的第一种情况下,变量 item 的类型为 System.Object

使用 Linq 完成的 for-each 可能如下所示:

foreach (Word.Language item in oWord.Languages.Cast<Word.Language>()
.Where(item => item.NameLocal.IndexOf(strTgtLanguage, StringComparison.Ordinal) > -1))
{
    selection.LanguageID = item.ID;
    break;
}

或者 for-each 可以替换为例如FirstOrDefault:

Word.Language hungarian =
oWord.Languages.Cast<Word.Language>()
.FirstOrDefault(item => item.NameLocal.IndexOf(strTgtLanguage, StringComparison.Ordinal) > -1);

if (hungarian != null)
    selection.LanguageID = hungarian.ID;

Languages 是一个 IEnumerable,因此您需要显式声明迭代变量。

如果您使用 IEnumerable 的 .Cast<>() 方法,您可以访问 .Any() 函数以避免自己编写迭代循环。

两个版本如下:

using wd = Microsoft.Office.Interop.Word;

wd.Application oWord = new wd.Application();
wd.Document oWordDoc = new wd.Document();
wd.Selection oWordSelection = oWordDoc.ActiveWindow.Selection;

// foreach loop
foreach (wd.Language item in oWord.Languages)
{
    Console.WriteLine(item.ID);
    if (item.NameLocal.IndexOf("Hungarian") > -1)
    {
        oWordSelection.LanguageID = item.ID;
        break;
    }
}

// linq
if (oWord.Languages.Cast<wd.Language>().Any(lang => lang.NameLocal.IndexOf("Hungarian") > -1))
    oWordSelection.LanguageID = wd.WdLanguageID.wdHungarian;