回到基础:var!= Dim

Someone said today after seeing the C# var operator for implicitly typed variables, "Oh, now C# has Dim." Well, not exactly. Not even close.

在看到C#var运算符用于隐式类型的变量后,今天有人说:“哦,现在C#具有Dim。” 好吧,不完全是。 差远了。

I like what this C# tutorial says about var.

我喜欢本C#教程中有关var的内容

...[var is] a new keyword that means, "I want to declare a variable, but I’m too lazy to write out its type."

... [var是]一个新关键字,意思是“我想声明一个变量,但是我懒得写出它的类型。”

One way to look at the power of VB's Dim operator is to say,

查看VB的Dim运算符功能的一种方法是,

Dim kind of means, "I want to declare a variable but I can't tell you much about how it behaves until much later."

有点暗淡的意思是,“我想声明一个变量,但是直到很久以后我才能告诉您很多有关它的行为的信息。”

Dim lets you do actual late-binding while in C# (today) you do late-binding with reflection. I wanted to find a way to clearly express this in a very visceral sample.

Dim使您可以进行实际的后期绑定,而在C#中(今天),您可以通过反射进行后期绑定。 我想找到一种在非常内在的样本中清楚表达这一点的方法。

A friend wanted to change a value in the CustomDocumentProperties in Word and see that change reflected in an updated field. In the document properties dialog below, you can see there's a "CustomProperty1" that has the value of "Scott" in it. Then in the document, there's a Field that is bound to that property. It's not meant to be a mail merge, but more of a MadLibs kind of a thing for writing applications that update forms and templates within Word or Excel documents.

一位朋友想在Word中的CustomDocumentProperties中更改一个值,并希望该更改反映在更新的字段中。 在下面的文档属性对话框中,您可以看到其中具有“ Scott”值的“ CustomProperty1”。 然后在文档中,有一个绑定到该属性的字段。 这并不意味着要进行邮件合并,而更像是MadLibs ,用于编写可更新Word或Excel文档中的表单和模板的应用程序。

image

His language of choice is C#, so he started off in C#. He added a reference to the Microsoft.Office.Interop.Word PIA (Primary Interop Assembly) and fought with the  system for some hours. After a while, I got enlisted, and after I figured out that the specific COM interface he needed was a late-bound IDispatch interface, we were able to crack with the Reflection.

他选择的语言是C#,因此他从C#开始。 他添加了对Microsoft.Office.Interop.Word PIA(主要Interop程序集)的引用,并与系统进行了数小时的奋战。 过了一会儿,我被征召入伍,并弄清他需要的特定COM接口是后期绑定的IDispatch接口,我们得以使用Reflection进行破解。

I'm starting to think of Reflection much the way I think about Regular Expressions. If you have to solve your Problem with Reflection, you may just end up with Problems, plural!

我开始思考反射的方式与思考正则表达式的方式相同。 如果必须使用反射解决问题,则可能会遇到问题,即复数!

Notice a few things. First, the need for some of those obvious strings and booleans to be of type Object. Notice all the System.Reflection.Missing.Values passed by reference. Most of all, notice the custom GetCustomPropertyValue and SetCustomPropertyValue that had to use Reflection.

注意几件事。 首先,需要将某些显而易见的字符串和布尔类型设为对象类型。 注意通过引用传递的所有System.Reflection.Missing.Values。 最重要的是,请注意必须使用反射的自定义GetCustomPropertyValue和SetCustomPropertyValue。

  ApplicationClass WordApp = new ApplicationClass();
WordApp.Visible = true;
object missing = System.Reflection.Missing.Value;
object readOnly = false;
object isVisible = true;
object fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\NewTest.doc");
Microsoft.Office.Interop.Word.Document aDoc = WordApp.Documents.Open(
ref fileName,ref missing,ref readOnly,ref missing,
ref missing,ref missing,ref missing,ref missing,
ref missing,ref missing,ref missing,ref isVisible,
ref missing,ref missing,ref missing,ref missing);

aDoc.Activate();

string propertyValue = GetCustomPropertyValue(aDoc, "CustomProperty1");
SetCustomPropertyValue(aDoc, "CustomProperty1", "Hanselman");

foreach (Range r in aDoc.StoryRanges)
{
r.Fields.Update();
}
}

public string GetCustomPropertyValue(Document doc, string propertyName)
{
object oDocCustomProps = doc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
object oCustomProp = typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null, oDocCustomProps,
new object[] { propertyName });

Type typePropertyValue = oCustomProp.GetType();
string propertyValue = typePropertyValue.InvokeMember("Value",
BindingFlags.Default |
BindingFlags.GetProperty,
null, oCustomProp,
new object[] { }).ToString();

return propertyValue;
}

public void SetCustomPropertyValue(Document doc, string propertyName, string propertyValue)
{
object oDocCustomProps = doc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.SetProperty,
null, oDocCustomProps,
new object[] { propertyName, propertyValue });
}

There's a great article from 7 (yes SE7EN) years ago on Dr. Dobb's about Invoking COM Components from C# that provided me this diagram. The RCW (Runtime Callable Wrapper) sits in front of the COM Object and makes my reflection calls work.

有7年前(是SE7EN)关于Dobb博士的一篇很棒的文章,内容涉及从C#调用COM组件,这为我提供了这张图。 RCW(运行时可调用包装程序)位于COM对象的前面,使我的反射调用正常工作。

Sure, I could have created some IDL and laid out an IDispatch implementation for these CustomDocumentProperties, but that's getting REALLY involved. Actually, there's supposed to be an implementation for CustomDocumentProperties but the MSDN Sample fails with this:

当然,我可以创建一些IDL并为这些CustomDocumentProperty设计一个IDispatch实现,但这确实涉及其中。 实际上,应该有一个CustomDocumentProperties的实现,但是MSDN Sample失败了:

"Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Office.Core.DocumentProperties'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))."

“无法将类型为'System .__ ComObject'的COM对象转换为接口类型'Microsoft.Office.Core.DocumentProperties'。此操作失败,因为对具有IID'{2DF8D04D-5BFA-101B- BDE5-00AA0044DE52}'由于以下错误而失败:不支持此类接口(HRESULT的异常:0x80004002(E_NOINTERFACE))。

Competing with that non-working MSDN sample is this KB article from 2007 that provided the bulk of the yucky, but straightforward reflection code.

与该无效的MSDN示例相对应的是2007年的这篇KB文章,其中提供了大量令人讨厌但简单的反射代码。

Why is this a Back to Basics post? Well, two fold. First, COM is Old and it's Basic. Seriously, though, the secondly (and only) reason is that, in my opinion, C# 3.0 is lousy for this kind of late-bound, COM-interop, Office Automation work.

为什么这是“回到基础知识”帖子? 好吧,两折。 首先,COM很老,很基础。 但是,严重的是,第二个(也是唯一一个)原因是,在我看来,C#3.0对于这种后期绑定,COM互操作的Office Automation工作是糟糕的。

Don't believe me? Here's the same code in VB. See the named parameters on the Open()? Notice the late-bound COM stuff just works without Reflection? (I've got Option Strict to Off for this code)

不相信我吗这是VB中的相同代码。 看到Open()上的命名参数了吗? 请注意,后期绑定的COM内容无需反射即可使用? (对于此代码,我将Option Strict设置为Off)

Dim WordApp = New Microsoft.Office.Interop.Word.ApplicationClass
WordApp.Visible = True

Dim fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\..\..\NewTest.doc")
Dim aDoc As Document = WordApp.Documents.Open(FileName:=fileName, ReadOnly:=True, Visible:=True)
aDoc.Activate()

Dim PROP = "CustomProperty1"
Dim propertyValue = aDoc.CustomDocumentProperties(PROP).Value
aDoc.CustomDocumentProperties(PROP).Value = "Hanselman"
For Each r As Range In aDoc.StoryRanges
r.Fields.Update()
Next

VB.NET is really well suited for this kind of thing, and my buddy will likely use it in this scenario.

VB.NET确实非常适合这种事情,我的朋友可能会在这种情况下使用它。

I hear this big difference in dynamism will change for the next version of C#. I'll talk to the team and try to get some details or rewrite my C# sample in C#.Next. I've also asked John Lam to help me write this sample in IronRuby. I suppose it'd look nice in PowerShell also.

我听说对于下一个版本的C#,动态性的巨大差异将改变。 我将与团队联系,并尝试获取一些详细信息或在C#中重写我的C#示例。 我还请John Lam帮助我用IronRuby编写此示例。 我想它在PowerShell中也看起来不错。

The Point is, and until some future date, var != Dim.

要点是,直到某个将来的日期,var!= Dim。

The Back to Basics thing to remember is that the language you know might not always be suited for the problem you have. Just because you CAN solve a problem in a certain language doesn't mean that you should. If something REALLY doesn't feel right in a certain language, ask around, perhaps there's another that makes more sense for what you're trying to do.

记住基础知识是,您所知道语言可能并不总是适合您遇到的问题。 仅仅因为您可以用某种语言解决问题,并不意味着您应该这样做。 如果某种语言确实不适用于某一种语言,请四处询问,也许还有另一种语言对您尝试做的事情更有意义。

翻译自: https://www.hanselman.com/blog/back-to-basics-var-dim

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值