将命名空间传递给函数

发布于 2024-10-21 12:32:36 字数 1312 浏览 5 评论 0原文

我有一个函数,它接受一个 Word 文档并将其保存为 html 格式。我想使用相同的函数来处理任何文档类型。我尝试过使用泛型(我假设不同的文档 API 是相同的),但由于 Jon Skeet 指出的原因而失败。还有别的办法吗?

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

//Works ok
private void convertDocToHtm( string filename )
{
... snip

     var app = new Word.Application();
     var doc = new Word.Document();
     doc = app.Documents.Open(ref fileName, ref missing, ref trueValue, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

... snip    
}

//fails dismally (to compile) because 'T' is a 'type parameter', which is not valid in the given context - i.e Word is a namespace not a class
private void convertDocToHtm2<T>( string filename )
{
... snip

     var app = new T.Application();
     var doc = new T.Document();
     doc = app.Documents.Open(ref fileName, ref missing, ref trueValue, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

... snip
}

//calling examples
convertDocToHtm( filename );
convertDocToHtm2<Word>( filename );
convertDocToHtm2<Excel>( filename );

I've got a function which takes a word document and saves it in html format. I'd like to use the same function to work with any document type. I've tried using generics (I'm assumming the different doc APIs are the same) which fails due to the reason Jon Skeet pointed out. Is there another way?

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

//Works ok
private void convertDocToHtm( string filename )
{
... snip

     var app = new Word.Application();
     var doc = new Word.Document();
     doc = app.Documents.Open(ref fileName, ref missing, ref trueValue, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

... snip    
}

//fails dismally (to compile) because 'T' is a 'type parameter', which is not valid in the given context - i.e Word is a namespace not a class
private void convertDocToHtm2<T>( string filename )
{
... snip

     var app = new T.Application();
     var doc = new T.Document();
     doc = app.Documents.Open(ref fileName, ref missing, ref trueValue, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

... snip
}

//calling examples
convertDocToHtm( filename );
convertDocToHtm2<Word>( filename );
convertDocToHtm2<Excel>( filename );

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

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

发布评论

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

评论(4

巴黎盛开的樱花 2024-10-28 12:32:36

不,这是不可能的。类型参数适用于类型,而不是命名空间

特别是,编译器无法验证这种类型是否存在 - 例如,您可以调用 ConvertDocToHtm2

使用 C# 4 中的动态类型,您可以执行以下操作:

private void ConvertDocToHtm2<TApplication>(string filename)
    where TApplication : new()
{
     dynamic app = new TApplication();
     dynamic doc = app.Documents.Open(filename, html: trueValue);
     // Other stuff here
}

然后:(

ConvertDocToHtm2<Word.Application>(filename);

顺便说一句,我已经猜测了 trueValue 的参数名称 - 您需要验证那。)

No, this isn't possible. Type parameters are for types, not namespaces.

In particular, the compiler couldn't verify that such a type even existed - you could call ConvertDocToHtm2<System> for example.

With dynamic typing in C# 4, you could do something this:

private void ConvertDocToHtm2<TApplication>(string filename)
    where TApplication : new()
{
     dynamic app = new TApplication();
     dynamic doc = app.Documents.Open(filename, html: trueValue);
     // Other stuff here
}

Then:

ConvertDocToHtm2<Word.Application>(filename);

(I've guessed at the parameter name for trueValue by the way - you'd want to verify that.)

似最初 2024-10-28 12:32:36

一旦您拥有对象动态可能很适合这里(用于调用方法和访问属性等) - 但是, > 适用于变量,而不是命名空间。

如果您确实需要命名空间(我认为您不需要),您可以将其作为字符串传递并使用 Activator.CreateInstance(namespace + ".Application")。

然而,阅读它 - 似乎只需要应用程序;也许:

private void convertDocToHtm2<T>( string filename ) where T : class, new();
{
     dynamic app = new T();
     dynamic doc = app.Documents.Open(fileName);

     // etc
}

并调用 convertDocToHtm2(filename)

Once you have the objects, dynamic may be a good fit here (for calling methods and accessing properties etc) - however, that only applies to variables, not namespaces.

If you really need the namespace (I don't think you do), you could pass it in as a string and use Activator.CreateInstance(namespace + ".Application").

However, reading it - it seems that only the application is needed; perhaps:

private void convertDocToHtm2<T>( string filename ) where T : class, new();
{
     dynamic app = new T();
     dynamic doc = app.Documents.Open(fileName);

     // etc
}

and call as convertDocToHtm2<Word.Application>(filename)

赴月观长安 2024-10-28 12:32:36

这是不可能的,因为 C# 中的泛型是编译时功能,并且类型必须在编译时已知。这是不可能的,因为不同 Office 应用程序的 API 不共享公共基类。在 C++ 中它可以工作,因为 C++ 模板被编译成在运行时评估的类。但即便如此,它也只适用于 API 的一小部分,因为它们相同!

That's not possible, because generics in C# are a compile time feature and the type must be known at compile time. That's not possible, because the APIs of the different Office Applications don't share a common base class. In C++ it could work, because the C++ templates are compiled into classes that are evaluated at runtime. But even then it would only work for small parts of the API, because they are not the same!

怪异←思 2024-10-28 12:32:36

如果您不想使用动态类型,并且仅在每个命名空间中使用一些方法,并且这些方法具有相同的签名,则可以构造 ConvertDocToHtml2 来接受委托。然后将 Word/Excel 下的方法作为这些委托传递。

If you don't want to use dynamic types, and if you only use a few methods in each namespace, and if those methods have the same signature, you can construct your ConvertDocToHtml2 to accept delegates. Then pass the methods under Word/Excel as those delegates.

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