C# 如何避免在构造函数中分配私有成员
我经常发现自己在这样做:C# 如何避免在构造函数中分配私有成员,c#,C#,我经常发现自己在这样做: class MyClass { public MyClass(int x) { this.x = x; } private int x; ... } 每次为配置添加新的私有成员变量时,我都需要将其添加到构造函数的参数列表、构造函数体以及类中作为成员。有没有一种好的编程模式可以避免额外的键入?一般来说,如果你实例化一个包含大量私有成员的类,而这些成员必须传递给构造函数,那么你已经在做一些有问题的事
class MyClass
{
public MyClass(int x)
{
this.x = x;
}
private int x;
...
}
每次为配置添加新的私有成员变量时,我都需要将其添加到构造函数的参数列表、构造函数体以及类中作为成员。有没有一种好的编程模式可以避免额外的键入?一般来说,如果你实例化一个包含大量私有成员的类,而这些成员必须传递给构造函数,那么你已经在做一些有问题的事情了
MyClass myClass = new MyClass(x, y, z, 7, 'c', someOtherClass)
如果合适,可以将相关字段封装到结构或其他类中,如下所示
class MyClass
{
public MyClass(Coordinates coords)
{
this.coords = coords;
}
private Coordinates coords;
}
public struct Coordinates
{
public int X{get; set;}
public int Y{get; set;}
public int z{get; set;}
}
然后你可以把它和
MyClass myClass = new MyClass(new Coordinates() { X = 1, Y = 2, Z = 3 });
如果没有特定的实现,就很难确定最佳解决方案,但是如果您实际上不必在类之外设置字段,您可以执行以下操作
class MyClass
{
public MyClass()
{
}
private int x = 2;
...
}
或
我发现我可以滥用继承来实现我的目标。我建立了一个“Loader”子类,它的唯一目的是插入基类的依赖项。然后我们可以使用基类,而不用考虑加载器 同样,这会产生可怕的副作用,阻止在基构造函数中使用这些受保护的成员变量——我们需要使用.Start()函数或类似的函数。因此,这是一个非常糟糕的解决方案,尽管可以节省一些击键次数
public class MyClass
{
protected int param1;
protected int param2;
public void DoStuff()
{
Console.WriteLine(param1 + param2);
}
}
public class MyClassLoader : MyClass
{
public MyClassLoader()
{
param1 = 1;
param2 = 2;
}
}
class Program
{
static void Main(string[] args)
{
MyClass myObj = new MyClassLoader();
myObj.DoStuff();
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}
不这样认为,不,不幸的是,由于更改发生在3个不同的地方,因此不利于使用代码段、宏、加载项等。这是我最喜欢的Resharper功能之一。我向构造函数添加一个新参数,按Alt Enter键,Enter键,它会为该参数初始化一个新字段。1)这实际上并没有回答问题2)这通常是不可能的。显然,如果您在编译时知道该值,您将对其进行硬编码;但是需要接受它作为参数是很常见的。感谢您提出用配置参数传递结构。我更喜欢这种语法。但是,这并不是很有帮助,因为在内部,每次您想要访问该配置结构的成员时,都会有更多的输入。结果是在一天结束时输入更多的内容。@ChrisMerck“更多的内容”本身并不是你应该担心的问题。实际上,您应该担心的是,当您必须在多个地方进行相同的更改时(有时您可能会忘记一个),您还必须担心一个月后是否能够阅读自己的代码(甚至其他人阅读)。
public class MyClass
{
protected int param1;
protected int param2;
public void DoStuff()
{
Console.WriteLine(param1 + param2);
}
}
public class MyClassLoader : MyClass
{
public MyClassLoader()
{
param1 = 1;
param2 = 2;
}
}
class Program
{
static void Main(string[] args)
{
MyClass myObj = new MyClassLoader();
myObj.DoStuff();
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}