c# - 我可以强制 POCO 中的字段只在类型初始化程序中设置吗?

标签 c# poco code-analysis cql ndepend

如果我有这样的 POCO:

[Poco]
public class MyPoco
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
}

...它是这样初始化的:

new MyPoco { FirstName = "Joe", LastName="Bloggs", Address="123 Abc St." }

我能否在 NDepend 中使用 CQL,确保仅使用上述对象初始化程序设置属性,而不是单独设置。

我正试图捕捉这样的代码:

myPoco.FirstName="John";
doSomething(myPoco);

...我不希望人们在现有的 POCO 上设置属性。我知道我可以将 setter 设置为 private,但我不喜欢在构造函数中传递所有属性,因为您最终会得到一个签名,例如 MyPoco(string, string, string) - 更容易错位参数(比使用对象初始化语法更容易)

所以,我想使用 NDepend 捕捉它。这是我的 CQL 查询的开始:

from f in JustMyCode.Fields.Where(f=>
   f.ParentType.HasAttribute ("JetBrains.Annotations.PocoAttribute".AllowNoMatch())) 
       where f.MethodsAssigningMe [I'M STUMPED HERE]

看起来我可以分析设置 POCO 属性的方法,但我需要更进一步并检查代码块以查看它是否在对象初始化程序 block 中。

这可能吗?

最佳答案

我不知道您是否可以在 CQL 中执行此操作,尽管即使您不能,您也可以使用 Roslyn 执行此操作。

但是,您可能需要考虑改用构建器模式:

var poco = new MyPoco.Builder { FirstName = "Joe",
                                LastName="Bloggs",
                                Address="123 Abc St." }.Build();

现在 poco 本身可以是不可变的,但是构建器可以在任何你喜欢的地方设置属性。

哎呀,如果你是隐式转换的粉丝,你可以甚至有一个从构建器到 poco 的隐式转换:

MyPoco poco = new MyPoco.Builder { FirstName = "Joe",
                                   LastName="Bloggs",
                                   Address="123 Abc St." };

虽然我完全支持验证正确编码的工具,但在无法设计类型以避免一开始就被滥用的情况下,我更希望有一个白痴证明的 API 开始:)

另请注意,在 C# 4 中使用命名参数,甚至可以明确构造函数版本:

var poco = new MyPoco(firstName: "Joe",
                      lastName: "Bloggs",
                      address: "123 Abc St.");

当然,这仍然允许人们在没有命名参数的情况下编写它...

关于c# - 我可以强制 POCO 中的字段只在类型初始化程序中设置吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24322955/

相关文章:

c# - 从 txt 文件中查找附加文本

c# - EF 4.1 - 无法将一个实体与另一个现有实体相关联(可空 FK)

c# - EF反向POCO生成器: Failed to load provider EntityClient

c# - 从表中查询数据时管理实体的最佳实践?

c# - C# 代码可以以编译器(或语言)版本为条件吗?

java - 获取 Groovy-Java 项目方法的所有调用者的代码

c# - 将 URI 映射到 LINQ-to-SQL 中的字符串字段

c# - 以 ? 结尾的变量类型

c# - 将标志拆分为规范化表

c++ - 可视化代码流的工具 (C/C++)