英文:
Make property in abstract class only settable in constructor of child class?
问题
我在一个具体类中有一个仅支持get
的属性。根据定义,该属性只能在该类的构造函数中设置。后来我决定将这个属性放到一个没有构造函数的抽象类中,而具体类继承自该抽象类。如何使现在在抽象类中的属性只能在子类的构造函数中设置?
不会起作用的解决方案:
- 如果我给属性添加
protected set
修饰符,那么子类将具有比我要求的更多权限。 init
不是一个选项,因为我只想在构造函数中设置它。readonly
不一定会起作用,因为我使用的是C# 7.3。
示例原始类:
public class FooOriginal
{
public int IntHere { get; }
}
示例抽象类:
public abstract class FooAbstract
{
public int IntHere { get; }
}
示例子类:
public class FooChild : FooAbstract
{
public FooChild()
{
// 不会编译,因为IntHere是只读的。
intHere = 3;
}
}
英文:
I have a get
-only property in a concrete class. By definition, that can only be set in a constructor of that class. I later decide that I want this property to belong to a constructor-less abstract class that the concrete class inherits from. How can I make the property that is now in the abstract class only capable of being set within the constructors of the child classes?
Solutions that won't work:
- If I give the property a
protected set
modifier, then allows the child class more power than I'm asking for. init
isn't an option because I only want it set in the constructor.readonly
won't always work, because I'm on C# 7.3.
Example original class:
public class FooOriginal
{
public int IntHere { get; }
}
Example abstract class:
public abstract class FooAbstract
{
public int IntHere { get; }
}
Example child class
public class FooChild : FooAbstract
{
public FooChild()
{
// Won't compile because IntHere is get-only.
intHere = 3;
}
}
答案1
得分: 4
为了实现这一点,您可以给基类添加一个构造函数,如果您喜欢,可以将其设置为protected
:
public abstract class FooAbstract
{
public int IntHere { get; }
protected FooAbstract(int intHere)
{
IntHere = intHere;
}
}
然后,您的旧类可以调用基类构造函数,例如:
public class FooOriginal : FooAbstract
{
public FooOriginal(int intHere)
: base(intHere) // <-- 这就是魔法
{
}
}
或者,如果您想按照您的示例传递一个常量值:
public FooOriginal() : base(3)
{
}
英文:
To achieve this, you can give the base class a constructor, you can make it protected
if you like:
public abstract class FooAbstract
{
public int IntHere { get; }
protected FooAbstract(int intHere)
{
IntHere = intHere;
}
}
And your old can call the base class constructor, for example:
public class FooOriginal : FooAbstract
{
public FooOriginal(int intHere)
: base(intHere) // <-- This is the magic
{
}
}
Or if you want to pass in a constant value as per your example:
public FooOriginal() : base(3)
{
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论