在 C# 中生成不可变值对象:PostSharp 或 T4 模板?
我厌倦了样板不可变值对象代码。 PostSharp 或 T4 模板是否允许我进行以下转换?
输入:
public struct Name
{
public string FirstName;
public string LastName;
}
输出:
public struct Name : IEquatable<Name>
{
private readonly string firstName;
private readonly string lastName;
public string FirstName { get { return this.firstName; } }
public string LastName { get { return this.lastName; } }
public Name(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public bool Equals(Name other)
{
return this.FirstName == other.FirstName && this.LastName == other.LastName;
}
public override bool Equals(object obj)
{
return obj is Name && this.Equals((Name)obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
if (this.FirstName != null)
{
hash = hash * 29 + this.FirstName.GetHashCode();
}
if (this.LastName != null)
{
hash = hash * 29 + this.LastName.GetHashCode();
}
return hash;
}
}
public static bool operator==(Name a, Name b)
{
return a.Equals(b);
}
public static bool operator !=(Name a, Name b)
{
return !(a == b);
}
}
显然 PostSharp 需要一个 [MakeImmutable]
注释,这很好。我想要根据原始类型生成 class
或 struct
的选项。另请注意,GetHashCode
必须省略对值类型成员的 null
检查。
我相当确定这两种技术都具有这种功能,但我自己只是 PostSharp 方面/T4 模板的使用者,所以我不知道哪种技术对于这项任务来说更好或更容易。无论你给出哪个答案,我都会花一两天的时间学习足够的知识来完成这项工作:)。
I'm getting sick of boilerplate immutable value object code. Would either PostSharp or T4 templates allow me to do the following transformation?
Input:
public struct Name
{
public string FirstName;
public string LastName;
}
Output:
public struct Name : IEquatable<Name>
{
private readonly string firstName;
private readonly string lastName;
public string FirstName { get { return this.firstName; } }
public string LastName { get { return this.lastName; } }
public Name(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public bool Equals(Name other)
{
return this.FirstName == other.FirstName && this.LastName == other.LastName;
}
public override bool Equals(object obj)
{
return obj is Name && this.Equals((Name)obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
if (this.FirstName != null)
{
hash = hash * 29 + this.FirstName.GetHashCode();
}
if (this.LastName != null)
{
hash = hash * 29 + this.LastName.GetHashCode();
}
return hash;
}
}
public static bool operator==(Name a, Name b)
{
return a.Equals(b);
}
public static bool operator !=(Name a, Name b)
{
return !(a == b);
}
}
Obviously PostSharp would require a [MakeImmutable]
annotation, which is fine. I'd want the option of generating either a class
or struct
depending on the original type. Also note that GetHashCode
would have to omit the null
checks for value-type members.
I am fairly sure either technology has this capability, but having not been anything but a consumer of PostSharp aspects/T4 templates myself, I don't know which would be a better or easier one for this task. Whichever answer you give, I'll go spend a day or two learning enough to make this work :).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我最近做了一些事情,可以满足您的要求(使用 T4 模板),所以这是绝对可能的:
https://github .com/xaviergonz/T4Immutable
例如,给定以下内容:
它将在单独的部分类文件中自动为您生成以下内容:
lastName, int age = 18) 将初始化这些值。
它还将为您添加 IEquatable 接口。在职的
运算符==和运算符!=的
所以它将生成这个(不包括一些冗余属性)
:项目页面中解释了更多功能。
I made something that does what you ask recently (using T4 templates), so it is absolutely possible:
https://github.com/xaviergonz/T4Immutable
For example, given this:
It will automatically generate for you in a separate partial class file the following:
lastName, int age = 18) that will initialize the values.
Also it will add the IEquatable interface for you. Working
implementations for operator== and operator!=
So it will generate this (excluding some redundant attributes):
And there are some more features as explained in the project page.
看起来您只想用样板文件来装饰您的结构,因此 PostSharp 将是最佳选择。原因是因为使用 T4,您需要
的出色 T4 示例
请参阅 http://table2dto.codeplex.com 了解执行此操作 您需要使用 EnvDTE(请参阅 http://dfactor.codeplex.com 了解如何这样做)
问题是,如果您需要生成在设计时需要使用的样板代码(看起来您没有任何东西),那么需要一些思考才能让 PostSharp 为您工作。
PostSharp 将是您最好的选择。
It looks like you want to just decorate your struct with boilerplate stuff, so PostSharp is going to be the way to go. The reason why is because with T4 you would need to
See http://table2dto.codeplex.com for great T4 example of doing this
To do this you would need to employ the use of EnvDTE (see http://dfactor.codeplex.com for code on how to do this)
The problem is, if you need to generate boilerplate code that you need to use at design time (which it doesnt look like you have anything) then it's going to require some thinking to get PostSharp to work for you.
PostSharp is going to be your best bet.
我建议为此使用 ReSharper:它可以在这种情况下很好地生成相等成员,因此您唯一需要编写的是一组属性 getter。
另请注意,通常您必须在
Equals
方法中区分结构体和对象,以便更快地检查相等性,因此如果这很重要,那么 T4 在这里不是一个好的选择。I'd recommend to use ReSharper for this: it generates equality members very well for such cases, so the only thing you must write is a set of property getters.
Also note that normally you must distinguish between structs and objects in
Equals
method to check the equality faster, so if this is important, T4 won't be a good choice here.