2011-03-10 245 views
1

我有一个函数,它将一个word文档保存为html格式。我想使用相同的功能来处理任何文档类型。我尝试过使用泛型(我假设不同的doc 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); 

回答

3

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

特别是,编译器无法验证这种类型是否存在 - 例如,您可以拨打ConvertDocToHtm2<System>

随着动态类型在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 - 你想验证一下。)

+0

嗯,看起来有趣,但我们仍然没有移动到.net 4 ... – Patrick 2011-03-10 10:29:52

+1

@Patrick:在这种情况下,我认为你会被卡住手动反射,或每个应用程序单独的方法。 – 2011-03-10 10:31:46

+1

无论如何,它是没有用的,因为'Excel.Application'不包含名为'Documents'的属性,所以这个方法只能用于Word文档。 – 2011-03-10 10:34:57

1

一旦你有对象dynamic在这里可能很适合(用于调用方法和访问属性等) - 但是,那只有适用于变量,而不是名称空间。

如果你真的需要命名空间(我不认为你这样做),你可以将它作为字符串传递并使用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<Word.Application>(filename)

1

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

1

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

相关问题