Ambiguity in Word Interop code [duplicate]

2019-02-16 19:10发布

问题:

This question already has an answer here:

  • Compile time warning when using 'Microsoft.Office.Interop.Word._Document.Close' 1 answer

I recently posted a question about reading Word files here.

The app runs fine however I get this Warning message;

Warning Ambiguity between method 'Microsoft.Office.Interop.Word._Document.Close(ref object, ref object, ref object)' and non-method 'Microsoft.Office.Interop.Word.DocumentEvents2_Event.Close'. Using method group.

There seems to be some ambiguity from some using namespace and I would like to know how to resolve this. Although the app runs, I would like to minimize warning/errors.

I have provided the code below for the class; The line it refers to are these two lines

docs.Close(ref nullobject, ref nullobject, ref nullobject);
wordObject.Quit(ref nullobject, ref nullobject, ref nullobject);

The whole code:

namespace Wizard.Classes
{
    class MSWordReader
    {
        public void read(String filename)
        {
            String buffer = "";
            try
            {
                Microsoft.Office.Interop.Word.Application wordObject = new   
                Microsoft.Office.Interop.Word.Application();
                object file = filename; //this is the path
                object nullobject = Type.Missing;
                object visible = false;
                object readonlyp = true;
                object addtorecent = false; //add to words recent filelist

                Microsoft.Office.Interop.Word.Document docs = wordObject.Documents.Open
                    (ref file,ref nullobject, ref readonlyp, ref addtorecent,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref visible,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject
                                    );
                docs.ActiveWindow.Selection.WholeStory();
                docs.ActiveWindow.Selection.Copy();
                IDataObject data = Clipboard.GetDataObject();
                buffer = data.GetData(DataFormats.Text).ToString();

                docs.Close(ref nullobject, ref nullobject, ref nullobject);

                wordObject.Quit(ref nullobject, ref nullobject, ref nullobject);
                MessageBox.Show(buffer);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

回答1:

To resolve the ambiguity, use:

((Microsoft.Office.Interop.Word._Document)docs).Close(ref nullobject, ref nullobject, ref nullobject);    
((Microsoft.Office.Interop.Word._Application)wordObject).Quit(ref nullobject, ref nullobject, ref nullobject);


回答2:

Try casting your docs first:

((_Document)docs).Close(ref nullobject, ref nullobject, ref nullobject);

The Microsoft.Office.Interop.Word.Document interface implements both the DocumentEvents2_Event and _Document interfaces. Each have a close method, and the compiler is having trouble determining which you mean.

Alternatively, you could declare your docs variable as a _Document in the first place:

Microsoft.Office.Interop.Word._Document docs = wordObject.Documents.Open ...

The same resolution can be used for ambiguities on your wordObject, casting it to an _Application.



回答3:

The proposed solutions works fine, but it leaves ReSharper with an Ambiguous Invocation error that you can't get rid of except for using the old "Ignore Errors" trick in the R# Errors dialog, even though the compiler is happy enough with it.

I couldn't really get a good solution from R# and it only comes up in a few places so the least-bad answer I found that works and doesn't produce either Visual Studio or R# errors is to cast to a dynamic.

((dynamic) Doc).Close();

Not ideal, but I just hold my nose and use it. If you are going to use it more than once you can obviously save to a dynamic variable. You could technically use the dynamic for everything (it's just late-bound COM), but you'd lose all intelliSense so I only use it on the few methods and events where it comes up.