在C#中是否有“passthrough”属性的简写方式?

huangapple go评论73阅读模式
英文:

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文本模板。我的目标是通过减少手工编写的代码量来降低出错的机会,以减少例如复制/粘贴代码时出错的机会。

在我的项目中,有CircleVertexSquareVertexTriangleVertex三种类型,每种类型都有单独的fillColorstrokeColor。这可以被视为嵌套循环,而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>



huangapple
  • 本文由 发表于 2020年1月6日 16:17:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/59608737.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定