何时使用私有属性(没有特殊逻辑)
When to use private properties (with no special logic)
最近我一直在阅读一些关于在 C# 中总是使用属性而不是 public 字段的话题,但是私有属性呢?当然,有一些讨论,但他们几乎总是在谈论额外的逻辑/延迟加载等。
假设我有一个只读字段,将在整个程序中访问 class,但(至少目前)它没有在其他任何地方使用:
static class Program
{
private static readonly Canvas canvas = new Canvas(100, 30);
// Canvas is like the main class of my game, there can be only one instance of it
static void Main()
{
// ...
canvas.DoSomething();
// ...
}
// ...
// Many other references to "canvas" here
}
或者我应该这样做:
private static Canvas Canvas { get; } = new Canvas(100, 30);
第二个选项意味着我可以很容易地做到这一点 public,我将来可能会或可能不会这样做。那么其他私有领域呢?关于什么应该是私有 属性 是否有任何规则或指南?或者我应该将所有内容都声明为一个字段,因为它是私有的(尽管感觉 public-ish)?
澄清一下:
- 我不是在制作可重复使用的库,只是一个主机游戏;
- 我不会实现任何关于获取/设置值的逻辑;
- 我自己写的 Canvas class,不是外来的。
使用私有属性是没有用的,因为只有当前 class 成员可以访问它并且它是可读写的。
除非你只想在构造函数或声明级别初始化它,并且不允许在其他方法中写入,所以你可以这样写:
private MyField { get; }
声明只读字段和这样的 属性 之间的区别在于 属性 读取访问器是一种方法,因此它会导致 CPU proc 调用 tick 在每次访问时消耗,即不需要只读 属性.
所以这是速度性能的问题,否则它是相同的最终结果。
这是一个测试class:
public class Test
{
private readonly int MyField = 10;
private int MyProperty { get; }
public Test()
{
MyProperty = 10;
}
public void Method()
{
var value1 = MyField;
var value2 = MyProperty;
}
}
这里是编译器生成的 IL 代码:
// int myField = MyField;
IL_0001: ldarg.0
IL_0002: ldfld int32 ConsoleApp.Test::MyField
IL_0007: stloc.0
// int myProperty = MyProperty;
IL_0008: ldarg.0
IL_0009: call instance int32 ConsoleApp.Test::get_MyProperty()
IL_000e: stloc.1
对于只读字段,只有将值加载到堆栈中,CLR 将其替换为目标处理器加载到寄存器指令中,即快速 (MOV)。
使用 属性 有一个 .NET 方法调用,CLR 将其替换为目标处理器过程调用指令,该指令消耗大量 CPU 滴答以及 return (CALL/RET).
.method private hidebysig specialname instance int32 get_MyProperty () cil managed
// return MyProperty;
IL_0000: ldarg.0
IL_0001: ldfld int32 ConsoleApp.Test::'<MyProperty>k__BackingField'
IL_0006: ret
所以 属性 比只读字段需要更多的 CPU 周期,但结果在操作方面是相同的(我会说一个错误的值,因为我不记得了x486,它很旧,但想象一下它可能会慢 5 到 20 倍。
因此,如果速度不是关键,这是一个偏好问题。您可以毫无问题地更改为 public,高级设计保持不变:速度和外观没有区别。
也就是说,请记住 public 属性对于 Visual Studio 设计器、组件设计和序列化是必需的。所以使用properties可能是一种时间的收获,也是一种更聪明的方式。
https://superuser.com/questions/643442/latency-of-cpu-instructions-on-x86-and-x64-processors
A 属性 是私有变量之上的包装。
私有 属性 与私有变量一样好。没有区别。
如果您不打算使用 class 之外的变量,那么只需使用变量
你也用过readonly。 readonly 的唯一目的是它只能在构造函数内部启动。
希望这能回答您的问题。
最近我一直在阅读一些关于在 C# 中总是使用属性而不是 public 字段的话题,但是私有属性呢?当然,有一些讨论,但他们几乎总是在谈论额外的逻辑/延迟加载等。
假设我有一个只读字段,将在整个程序中访问 class,但(至少目前)它没有在其他任何地方使用:
static class Program
{
private static readonly Canvas canvas = new Canvas(100, 30);
// Canvas is like the main class of my game, there can be only one instance of it
static void Main()
{
// ...
canvas.DoSomething();
// ...
}
// ...
// Many other references to "canvas" here
}
或者我应该这样做:
private static Canvas Canvas { get; } = new Canvas(100, 30);
第二个选项意味着我可以很容易地做到这一点 public,我将来可能会或可能不会这样做。那么其他私有领域呢?关于什么应该是私有 属性 是否有任何规则或指南?或者我应该将所有内容都声明为一个字段,因为它是私有的(尽管感觉 public-ish)?
澄清一下:
- 我不是在制作可重复使用的库,只是一个主机游戏;
- 我不会实现任何关于获取/设置值的逻辑;
- 我自己写的 Canvas class,不是外来的。
使用私有属性是没有用的,因为只有当前 class 成员可以访问它并且它是可读写的。
除非你只想在构造函数或声明级别初始化它,并且不允许在其他方法中写入,所以你可以这样写:
private MyField { get; }
声明只读字段和这样的 属性 之间的区别在于 属性 读取访问器是一种方法,因此它会导致 CPU proc 调用 tick 在每次访问时消耗,即不需要只读 属性.
所以这是速度性能的问题,否则它是相同的最终结果。
这是一个测试class:
public class Test
{
private readonly int MyField = 10;
private int MyProperty { get; }
public Test()
{
MyProperty = 10;
}
public void Method()
{
var value1 = MyField;
var value2 = MyProperty;
}
}
这里是编译器生成的 IL 代码:
// int myField = MyField;
IL_0001: ldarg.0
IL_0002: ldfld int32 ConsoleApp.Test::MyField
IL_0007: stloc.0
// int myProperty = MyProperty;
IL_0008: ldarg.0
IL_0009: call instance int32 ConsoleApp.Test::get_MyProperty()
IL_000e: stloc.1
对于只读字段,只有将值加载到堆栈中,CLR 将其替换为目标处理器加载到寄存器指令中,即快速 (MOV)。
使用 属性 有一个 .NET 方法调用,CLR 将其替换为目标处理器过程调用指令,该指令消耗大量 CPU 滴答以及 return (CALL/RET).
.method private hidebysig specialname instance int32 get_MyProperty () cil managed
// return MyProperty;
IL_0000: ldarg.0
IL_0001: ldfld int32 ConsoleApp.Test::'<MyProperty>k__BackingField'
IL_0006: ret
所以 属性 比只读字段需要更多的 CPU 周期,但结果在操作方面是相同的(我会说一个错误的值,因为我不记得了x486,它很旧,但想象一下它可能会慢 5 到 20 倍。
因此,如果速度不是关键,这是一个偏好问题。您可以毫无问题地更改为 public,高级设计保持不变:速度和外观没有区别。
也就是说,请记住 public 属性对于 Visual Studio 设计器、组件设计和序列化是必需的。所以使用properties可能是一种时间的收获,也是一种更聪明的方式。
https://superuser.com/questions/643442/latency-of-cpu-instructions-on-x86-and-x64-processors
A 属性 是私有变量之上的包装。
私有 属性 与私有变量一样好。没有区别。 如果您不打算使用 class 之外的变量,那么只需使用变量
你也用过readonly。 readonly 的唯一目的是它只能在构造函数内部启动。
希望这能回答您的问题。