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;
我正在将 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;