我可以阻止从字符串自动转换为 XName 吗?

Can I prevent the automatic casting from string to XName?

作为一个纯粹主义者,我讨厌看到字符串常量散布在我的代码中:

var x = element.Attribute("Key");

我喜欢将它们存储为单个引用常量,我喜欢我第一次在 Eric White 的 XmlPowerTools:

中看到的方法
public class MyNamespace {
  public static readonly XNamespace Namespace = "http://tempuri.org/schema";
  public static readonly XName Key = Namespace + "Key";
}

并使用:

var x = element.Attribute(MyNamespace.Key);

这样做的美妙之处在于,我可以使用 Visual Studio 或 Resharper 轻松找到对这些 static 字段的所有引用,而不必遍历每个找到的字符串实例 "Key" ,可想而知,用在了很多不相关的地方。

所以,我有一个遗留项目,我想将其转换为使用 XName 方法,并且需要找到所有使用字符串而不是 XName 的地方。我认为如果我可以停止将字符串自动转换为 XName,编译器会为我挑选所有这些事件。

我在查找中使用了正则表达式:

(Element|Attribute|Ancestor)s?\("

它拾取了那些结构,但后来我发现:

if (element.Name == "key")

想知道我还会错过什么。

问题是,如何停止将字符串自动转换为 XName,或者还有什么其他方法可以找到所有出现的应该是 XName 的字符串?

隐式运算符不能停止

另一方面,取自MSDN

XName does not contain any public constructors. Instead, this class provides an implicit conversion from String that allows you to create an XName

或者,您可以转换此代码:

if (element.Name == "key")

...进入:

   XName key = "key";

   if(element.Name == key)

顺便说一句,我觉得你会让事情变得过于复杂只是为了获得更多的可搜索性,而编码编程语言的目标是生成 可执行代码 并且你应该编写简单的代码尽可能提高可维护性和质量...

所以,有一种方法可以修复它,但不能阻止它(不包装 XName 库)。

删除对 XName 库的引用,使用相同的命名空间创建您自己的 XName class,但不提供字符串隐式转换。 尝试编译,你会发现所有地方都把一个字符串赋给了一个XName

您可能需要尝试使用它才能正确编译(例如,将新的 class 放入单独的库中,使 it只有它引用了XName库,而subclass原来的,所以在使用API中的对象时不会编译失败。

全部修复后,删除 class 并重新添加 XName 库。

为了防止将来发生这种情况,您可以编写一个 class,它提供到 XName 的隐式转换,但不能从字符串进行隐式转换。不幸的是,您需要更改整个代码库才能使用包装器。