指定命名空间的程序集

15

有没有办法在C#中指定程序集和命名空间?

例如,如果在项目中引用了PresentationFramework.AeroPresentationFramework.Luna这两个程序集,您可能会注意到它们都在相同的命名空间中共享相同的控件,但是实现不同。

ButtonChrome为例。它存在于Microsoft.Windows.Themes命名空间下的两个程序集中。

在XAML中,您可以将程序集与命名空间一起包含,因此这里没有问题。

xmlns:aeroTheme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:lunaTheme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna"

<aeroTheme:ButtonChrome ../>
<lunaTheme:ButtonChrome ../>

但是在C#的代码后台中,我找不到任何方法来创建PresentationFramework.Aero中的ButtonChrome实例。

以下代码在编译时会给我错误CS0433

using Microsoft.Windows.Themes;
// ...
ButtonChrome buttonChrome = new ButtonChrome();
错误 CS0433:类型“Microsoft.Windows.Themes.ButtonChrome”存在于以下两个位置:
'c:\Program Files(x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Profile\Client\PresentationFramework.Aero.dll'

'c:\Program Files(x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Profile\Client\PresentationFramework.Luna.dll'。
这是可以理解的,因为编译器不知道要选择哪个ButtonChrome,因为我没有告诉它。有什么办法可以解决吗?
3个回答

14

你需要为程序集引用指定一个别名,然后通过该别名导入:

extern alias thealias;

查看参考文献的属性窗口。

假设您将aero程序集别名为"aero",将luna程序集别名为"luna"。然后,您可以按照以下方式在同一文件中使用两种类型:

extern alias aero;
extern alias luna;

using lunatheme=luna::Microsoft.Windows.Themes;
using aerotheme=aero::Microsoft.Windows.Themes;

...

var lunaButtonChrome = new lunatheme.ButtonChrome();
var aeroButtonChrome = new aerotheme.ButtonChrome();

请查看extern alias了解更多信息。


谢谢Kent!对于PresentationFramework.Aero,我已将别名设置为aero,将Interop类型嵌入设置为False,但仍然出现“error CS0430:未在/reference选项中指定extern别名'aero'”。我还需要做些什么吗? - Fredrik Hedblad
很不幸,如果项目包含ResourceDictionaries,则似乎存在一个错误:http://connect.microsoft.com/VisualStudio/feedback/details/615953/reference-aliases-are-ignored-on-projects-containing-some-xaml-files。我尝试了没有任何XAML文件的情况,它可以工作。这个问题将在4.5中得到解决。再次感谢。 - Fredrik Hedblad
@Meleak:有趣——我不知道那个漏洞。你看到解决方法了吗?对你来说是一个选项吗? - Kent Boogaart
我看到了它,但我不喜欢绝对路径的那一部分。不过出于好玩我还是试了一下,而且它成功了。但这并不是我的唯一选择,所以我选择了另一条路。不过了解别名还是很有益的,我猜它们只在这种特殊情况下使用 :) - Fredrik Hedblad

6

外部别名来拯救,参见文档这里。在添加程序集引用并在相应的引用属性中创建别名Luna和Aero后,这里是一些示例代码供您尝试:

extern alias Aero;
extern alias Luna;

using System.Windows;

namespace WpfApplication1
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow: Window
  {
    public MainWindow()
    {
      InitializeComponent();

      var chrome1 = new Luna::Microsoft.Windows.Themes.ButtonChrome();
      var chrome2 = new Aero::Microsoft.Windows.Themes.ButtonChrome();
      MessageBox.Show(chrome1.GetType().AssemblyQualifiedName);
      MessageBox.Show(chrome2.GetType().AssemblyQualifiedName);
    }
  }
}

+1,谢谢!我这里还是有些问题,设置别名后,仍然出现“error CS0430:未在/reference选项中指定extern alias 'aero'”。你有什么想法吗? - Fredrik Hedblad
@Meleak:在“解决方案资源管理器”窗口中选择程序集引用,转到“属性”窗口,并将“别名”属性的值从“global”更改为“Luna”,“Aero”等。 - Alan
再次感谢。我已经这样做了,但不幸的是似乎存在一个错误。如果项目包含 ResourceDictionaries,则别名将被忽略:http://connect.microsoft.com/VisualStudio/feedback/details/615953/reference-aliases-are-ignored-on-projects-containing-some-xaml-files - Fredrik Hedblad
@Meleak:嗯,谢谢你提供的链接,我之前不知道这个bug。看起来至少在4.5版本中会修复它。 - Alan
是的,希望如此 :) 没有任何 XAML 文件,它运行得非常好。虽然我选择了肯特的答案,因为他最先回答了,但还是感谢你的帮助! - Fredrik Hedblad
1
@Meleak:不用谢。我实际上是在VS中输入了代码,所以Kent更快地到达了那里(他实际上编辑了最初不正确的答案,否则我会在发布之前放弃我的),但没关系,现在是周末时间,重要的是我们找到了问题的根源 :) - Alan

1
我遇到了一个类似的错误,涉及到Microsoft.Scripting程序集中引用的System.NonSerializedAttribute(在服务引用生成的Reference.cs文件中发现冲突)。解决这个问题的最简单方法与定义别名非常相似,但是不需要编译的烦恼:
在Visual Studio中,转到项目的引用,选择其中一个产生冲突的程序集,进入属性并将Aliases值填充为不等于global的其他内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接