分享

为什么默认情况下不使用C#“使用别名”?

 印度阿三17 2019-06-11

请考虑以下代码.

using System.ComponentModel.DataAnnotations;

namespace Foo
{
    public class Bar
    {
        [Required, MaxLength(250)]
        public virtual string Name { get; set; }
    }
}

除非你有一个花哨的IDE(即在幕后进行各种查找和静态分析),否则“必需”和“处理”的位置相当模糊. “MaxLength”实际上来自于.特别是当可能导入多个名称空间时,具有相似的含义.

作为C#的相对新手,我发现自己总是很难弄清楚某些事情的来源.特别是在查看StackOverflow等地方的其他代码片段时.

using DataAnnotations = System.ComponentModel.DataAnnotations;

namespace Foo
{
    public class Bar
    {
        [DataAnnotations.Required, DataAnnotations.MaxLength(250)]
        public virtual string Name { get; set; }
    }
}

现在很明显“必需”& “MaxLength”来自.您可以采取另一个步骤,并执行以下操作:

using Required = System.ComponentModel.DataAnnotations.RequiredAttribute;
using MaxLength = System.ComponentModel.DataAnnotations.MaxLengthAttribute;

namespace Foo
{
    public class Bar
    {
        [Required, MaxLength(250)]
        public virtual string Name { get; set; }
    }
}

这与PHP和& Js ES6有效.

我很好奇为什么这不是C#的默认值?为什么我和其他所有C#开发人员一起考虑别名的不良做法?是否存在一些潜在的性能原因?

解决方法:

为什么类型/定义来自何处?

如果您真正担心类型所在的命名空间,Visual Studio能够以多种方式查找,我最喜欢的两个是:

>将鼠标悬停在类型/声明中.这通常会显示完整的类型名称. (悬停新的SomeType()语句会显示方法名称,即应用于属性的方法名称.)
>按F12 /转到定义.即使您没有定义的来源,也可以使用F12或右键单击 – > “转到定义”将转到显示该类型的所有公共成员的元数据文件.这不适用于关键字(out,ref,return,null等),但它适用于基本别名类型(int,string等)和传统类型(枚举,接口,类,结构等).这包括命名空间,类型名称和所有公共API成员.如果有XML文档,也包含它们.如果您使用F12扩展方法,则会转到该扩展方法的类元数据.如果你觉得它是由一个本来不应该注入的东西注入的,那么这对于识别方法的来源非常有用.

所以现在确定该类型来自哪个命名空间并不困难.那么使用别名呢,我们什么时候才需要呢?

真实场景:我一直在为XNA Framework开发Windows窗体模型. XNA Framework有一个Color类型,我的框架有一个Color类型.现在我经常将这两个名称空间一起使用,但只需要本机使用其中一种颜色类型.通常我有一个using语句列表,其中包括:

using XnaColor = Microsoft.Xna.Framework.Color;
using Color = Evbpc.Framework.Drawing.Color;

所以这解决了一个含糊不清的问题.

为什么不使用别名作为默认值?

可能是因为他们几乎没有必要.我们真的不需要它们.如果你担心一个类型来自哪个命名空间,那么快速查找要比别名所有内容更容易,并强制定义命名空间.按照这个速度,您可以完全禁止使用语句并完全限定所有内容.

我用过别名的最大两个用例是:

>解决类型之间的歧义.见上面的例子.
>解决名称空间之间的歧义.与上面的想法相同,但如果复制了很多类型,我就会使用整个命名空间.

using XnaF = Microsoft.Xna.Framework;
using Evbpc.Framework.Drawing;

如果您使用Visual Studio生成代码,导入类型等,则不会使用别名.相反,Visual Studio将根据需要对名称进行完全限定.是否右键单击一个波形并将A.B.Type作为唯一选项而不是使用A.B?那通常是别名的好地方.

我会警告你,使用别名似乎增加了可维护性要求. (这可能没有备份数字,但我不会说谎 – 这个我有几个别名的项目会让我忘记我经常命名别名的方式.)

通常,根据我的经验,如果你必须使用使用别名,你可能在某个地方违反规则.

为什么我们不定期使用它们?

因为他们很糟糕.它们使代码更难阅读(以你的DataAnnotations.MaxLength为例,为什么我需要阅读它?我不关心MaxLength在System.ComponentModel.DataAnnotations中,我只关心它是否正确设置),它们会破坏代码(现在我不得不记住一个属性在System.ComponentModel.DataAnnotations而不是System.ComponentModel.DataAnnotations.Schema中),它们通常很笨重.

以前面的例子为例,我有一个实体框架项目,它在类上具有类似下面的属性:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Key, Column(Order = 2)]
[MaxLength(128)]
public string UserId { get; set; }

[ForeignKey(nameof(UserId))]
public virtual ApplicationUser User { get; set; }

现在用你的例子,我将有以下之一:

06003

要么:

06004

或者更糟糕的是:

06005

对不起,但那些都很可怕.这就是为什么你说话的’每个’开发者都会避开它们并认为这是一个坏主意.我将坚持智能地[1]导入名称空间并处理类型冲突的非常微小的潜力.然后我会使用别名.

如果你真的找不到类型所在的命名空间(比如你从Stack Overflow中提取代码),那么点击MSDN,转到Library并搜索类型. (即,搜索KeyAttribute或MaxLengthAttribute,第一个链接是API引用.)

[1]:聪明地说,我的意思是责任和关怀.不要盲目地导入/使用命名空间,尽量尽量限制它们. SRP和多​​态通常允许我们在每个文件中保持使用列表非常小.

来源:http://www./content-1-239151.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多