请考虑以下代码。
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#开发人员一起考虑别名的不良做法?是否存在一些潜在的性能原因?
答案 0 :(得分:7)
如果您真正关心类型所在的命名空间,Visual Studio能够以几种方式查找,我最喜欢的两种方式如下:< / p>
new SomeType()
语句会显示方法名称,即应用于属性的方法名称。)out
,ref
,return
,null
等),但它适用于基本别名类型(int
,string
等)和传统类型(enum
,interface
,class
,struct
等)。这包括命名空间,类型名称和所有公共API成员。如果有XML文档,也包含它们。如果 F12 是一个扩展方法,它会将您带到该扩展方法的类元数据。如果您觉得它是由不应该的东西注入的话,那么非常有助于识别方法的来源。所以现在它不是真的那么难以确定该类型来自哪个命名空间。那么using
别名呢,我们实际什么时候需要它们?
真实场景:我一直致力于XNA Framework的Windows窗体模型。 XNA Framework具有Color
类型,我的框架具有Color
类型。现在我经常将这两个命名空间一起使用,但只需要本地使用的{em>一个 Color
类型。我经常会有using
语句列表,其中包含以下内容:
using XnaColor = Microsoft.Xna.Framework.Color;
using Color = Evbpc.Framework.Drawing.Color;
因此,这解决了歧义问题。
using
别名为默认值?可能是因为他们几乎从不必要。我们不会真的需要它们。如果您关注某个类型的命名空间,那么远更容易进行快速查找,而不是别名所有内容和强制命名空间被定义为。按照这个速度,您可以完全禁止using
语句并完全限定所有内容。
using
别名,我曾经曾经的最大两个用例是:
解决命名空间之间的歧义。与上面的想法相同,但如果复制了很多类型,我会将整个命名空间别名。
using XnaF = Microsoft.Xna.Framework;
using Evbpc.Framework.Drawing;
如果您使用Visual Studio生成代码,导入类型等,则 将使用别名。相反,Visual Studio将根据需要对名称进行完全限定。是否右键单击了一个波形,并将A.B.Type
作为唯一选项,而不是using A.B
? 嗯,这通常是别名的好地方。
我会警告你,using
别名似乎会增加可维护性要求。 (这可能没有备份数字,但我不会说谎 - 这个我有几个别名的项目会让我忘记我经常命名别名的方式。)
通常,根据我的经验,如果您必须使用using
别名,则可能在某处违反规则。
因为他们很糟糕。他们让代码更难阅读(以DataAnnotations.MaxLength
为例,为什么我需要阅读?我不在乎MaxLength
在System.ComponentModel.DataAnnotations
,我只关心它已正确设置),它们会破坏代码(现在我强制要记住属性在System.ComponentModel.DataAnnotations
而不是System.ComponentModel.DataAnnotations.Schema
),而且它们通常只是笨重。
采用前面的示例,我有一个Entity Framework项目,该项目在类上具有类似以下的属性:
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; }
现在以您的示例为例,我将拥有以下其中一项:
using DataAnnotations = System.ComponentModel.DataAnnotations; [DataAnnotations.Key, DataAnnotations.Schema.Column(Order = 2)] [DataAnnotations.MaxLength(128)] public string UserId { get; set; } [DataAnnotations.Schema.ForeignKey(nameof(UserId))] public virtual ApplicationUser User { get; set; }
或者:
using DataAnnotations = System.ComponentModel.DataAnnotations; using Schema = System.ComponentModel.DataAnnotations.Schema; [DataAnnotations.Key, Schema.Column(Order = 2)] [DataAnnotations.MaxLength(128)] public string UserId { get; set; } [Schema.ForeignKey(nameof(UserId))] public virtual ApplicationUser User { get; set; }
或者更糟糕的是:
using KeyAttribute = System.ComponentModel.DataAnnotations.KeyAttribute; using MaxLengthAttribute = System.ComponentModel.DataAnnotations.MaxLengthAttribute; using ColumnAttribute = System.ComponentModel.DataAnnotations.Schema.ColumnAttribute; using ForeignKeyAttribute = System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute; [Key, Column(Order = 2)] [MaxLength(128)] public string UserId { get; set; } [ForeignKey(nameof(UserId))] public virtual ApplicationUser User { get; set; }
对不起,但那些只是可怕的。这就是为什么每一个&#39;你说话的开发人员避开它们并认为这是一个坏主意。我只是坚持智能 [1] 导入命名空间并处理类型冲突的非常小的潜力。 然后我会使用别名。
如果确实无法找到类型所在的命名空间(例如从Stack Overflow中提取代码),请点击MSDN,转到Library并搜索类型。 (即,搜索KeyAttribute
或MaxLengthAttribute
,第一个链接是API引用。)
[1]:聪明地 我的意思是责任和关怀。不要盲目地导入/使用命名空间,尽可能地限制它们。 SRP和多态通常允许我们在每个文件中保持using
列表非常小。