英文:
Is there a shorthand for "passthrough" properties in C#?
问题
我正在实现我的应用中的“保存/加载”功能。有各种类型的Vertex
对象,其中有很多静态字段,但显然不能序列化静态字段。我正在创建一个类,其实例包含这些字段,并且为了避免太多的代码来填充这些字段,我正在将它们实现为属性。
然而,要实现这个的语法似乎太繁琐了,所以我正在寻找一种简化的方法:
public Color CircleFillColor { get => CircleVertex.fillColor; set => CircleVertex.fillColor = value; }
public Color SquareFillColor { get => SquareVertex.fillColor; set => SquareVertex.fillColor = value; }
public Color TriangleFillColor { get => TriangleVertex.fillColor; set => TriangleVertex.fillColor = value; }
如果我们在C#中有宏,我可以像这样写:
#define passthru(F) { get => F; set => F = value; }
public Color CircleFillColor passthru(CircleVertex.fillColor)
public Color SquareFillColor passthru(SquareVertex.fillColor)
public Color TriangleFillColor passthru(TriangleVertex.fillColor)
是否有类似这样属性的简写方式?
英文:
I'm implementing a "save/load" function in my app. There are various types of Vertex
object that have a lot of static fields, but apparently you can't serialize static fields. I'm making a class whose instance contains these fields, and to avoid too much code to populate these fields I'm implementing them as properties.
However, the syntax to do this seems too bulky, so I'm looking for a way to simplify this:
public Color CircleFillColor { get => CircleVertex.fillColor; set => CircleVertex.fillColor = value; }
public Color SquareFillColor { get => SquareVertex.fillColor; set => SquareVertex.fillColor = value; }
public Color TriangleFillColor { get => TriangleVertex.fillColor; set => TriangleVertex.fillColor = value; }
If we had macros in C#, I could write something like this:
#define passthru(F) { get => F; set => F = value; }
public Color CircleFillColor passthru(CircleVertex.fillColor)
public Color SquareFillColor passthru(SquareVertex.fillColor)
public Color TriangleFillColor passthru(TriangleVertex.fillColor)
Is there any shorthand for properties like this?
答案1
得分: 1
没有直接等同于宏的功能。一个替代方法是封装这些调用,以最小的代价获得稍短的属性,但需要额外的两个方法,并将受影响的 fillColor
属性移到单个方法中,而不是在每个属性中重复两次。
public Color CircleFillColor { get => GetColor(CircleVertex); set => SetColor(CircleVertex, value); }
public Color SquareFillColor { get => GetColor(SquareVertex); set => SetColor(SquareVertex, value); }
public Color TriangleFillColor { get => GetColor(TriangleVertex); set => SetColor(TriangleVertex, value); }
private Vertex GetColor(Vertex vertex)
{
return vertex.fillColor;
}
private void SetColor(Vertex vertex, Color color)
{
vertex.fillColor = color;
}
英文:
There isn't a direct equivalent to macros. An alternative would be to encapsulate the calls which yields minimally shorter properties at the expense of two additional methods and moves the affected fillColor
property to a single method each instead of repeating it twice in every property.
public Color CircleFillColor { get => GetColor(CircleVertex); set => SetColor(CircleVertex, value); }
public Color SquareFillColor { get => GetColor(SquareVertex); set => SetColor(SquareVertex, value); }
public Color TriangleFillColor { get => GetColor(TriangleVertex); set => SetColor(TriangleVertex, value); }
private Vertex GetColor(Vertex vertex)
{
return vertex.fillColor;
}
private void SetColor(Vertex vertex, Color color)
{
vertex.fillColor = color;
}
答案2
得分: 0
我最终使用了Visual Studio中包含的T4文本模板。我的目标是通过减少手工编写的代码量来降低出错的机会,以减少例如复制/粘贴代码时出错的机会。
在我的项目中,有CircleVertex
、SquareVertex
和TriangleVertex
三种类型,每种类型都有单独的fillColor
和strokeColor
。这可以被视为嵌套循环,而T4允许以这种方式编写它。
以下是我最终使用的代码示例。相关的语法部分是,位于<# ... #>
内的部分是C#代码,而<#= foo #>
在遇到该行时将被替换为foo
的值。
<#
String[] shapes = new String[] {"Circle","Square","Triangle"};
String[] colors = new String[] {"fillColor", "strokeColor"};
foreach(var shape in shapes){
foreach(var color in colors){
#>
[XmlElement(Type = typeof(XmlColor))]
public Color <#=shape#>_<#=color#>
{
get => <#=shape#>Vertex.<#=color#>;
set => <#=color#>Vertex.<#=shape#> = value;
}
<#}#>
这会扩展为:
[XmlElement(Type = typeof(XmlColor))]
public Color Circle_fillColor
{
get => CircleVertex.fillColor;
set => CircleVertex.fillColor = value;
}
[XmlElement(Type = typeof(XmlColor))]
public Color Circle_strokeColor
{
get => CircleVertex.strokeColor;
set => CircleVertex.strokeColor = value;
}
[XmlElement(Type = typeof(XmlColor))]
public Color Square_fillColor
{
get => SquareVertex.fillColor;
set => SquareVertex.fillColor = value;
}
...snip...
[XmlElement(Type = typeof(XmlColor))]
public Color Triangle_strokeColor
{
get => TriangleVertex.strokeColor;
set => TriangleVertex.strokeColor = value;
}
英文:
I ended up using T4 text templates included in Visual Studio. As my goal was to reduce the amount of code that I needed to write by hand, so that there would be less of a chance to make a mistake while e.g. copy/pasting code.
In my project there are types of CircleVertex
, SquareVertex
and TriangleVertex
, each of which has a separate fillColor
and strokeColor
. This can be thought of as a nested loop, and T4 allows to write it this way.
As an example, here's the code I ended up using. The relevant syntax parts are that things in <# ... #>
is C# code, and <#= foo #>
is replaced with the value of foo
when this line is encountered.
<#
String[] shapes = new String[] {"Circle","Square","Triangle"};
String[] colors = new String[] {"fillColor", "strokeColor"};
foreach(var shape in shapes){
foreach(var color in colors){
#>
[XmlElement(Type = typeof(XmlColor))]
public Color <#=shape#>_<#=color#>
{
get => <#=shape#>Vertex.<#=color#>;
set => <#=color#>Vertex.<#=shape#> = value;
}
<#}#>
This expands to:
[XmlElement(Type = typeof(XmlColor))]
public Color Circle_fillColor
{
get => CircleVertex.fillColor;
set => CircleVertex.fillColor = value;
}
[XmlElement(Type = typeof(XmlColor))]
public Color Circle_strokeColor
{
get => CircleVertex.strokeColor;
set => CircleVertex.strokeColor = value;
}
[XmlElement(Type = typeof(XmlColor))]
public Color Square_fillColor
{
get => SquareVertex.fillColor;
set => SquareVertex.fillColor = value;
}
...snip...
[XmlElement(Type = typeof(XmlColor))]
public Color Triangle_strokeColor
{
get => TriangleVertex.strokeColor;
set => TriangleVertex.strokeColor = value;
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论