子 classes 中的 C# 方法是否可以具有不同的参数类型(派生自父 class 中方法的参数类型)?
Can C# methods in child classes have different argument type (that derives from an argument type for a method in parent class)?
抱歉,问题措辞不当。
我正在制作一些代表简单游戏 GUI 的 classes。 GUI 由不同的元素组成,由派生自某些共同祖先 UIElement 的 classes 表示。
class UIElement
{
public virtual void Update(UpdateArgs args) { }
public class UpdateArgs { }
}
每个元素都应包含一个 Update() 方法,但对于不同的元素,需要不同的参数(即,对于进度条,应该有一些数字表示已满,对于按钮,应该有一些布尔值来确定它是否可点击,等等在)。
所以基本上我希望能够覆盖 Update() 方法,将其参数类型更改为从原始方法的参数类型派生的类型,如下所示:
class ProgressBar : UIElement
{
public override void Update(UpdateArgs args)
{
base.Update(args);
//Set fullness
}
public class UpdateArgs : UIElement.UpdateArgs
{
double fullness;
}
}
上面的代码不起作用,因为编译器找不到合适的方法来覆盖(因为父 class 中没有 Update() 方法,它接受 ProgressBar.UpdateArgs 对象作为争论)。这是可以理解的,例如我可以实现 ProgressBar.UpdateArgs class 不是从 UIElement.UpdateArgs 派生的,这会导致错误和东西。
所以我的问题是,我怎样才能巧妙地实现上面描述的内容?是否有一些行为类似于嵌套 classes,但保证 if A : B
then A.nested : B.nested
?
我建议两种解决方案。
- 使用铸造类型
class UIElement
{
public virtual void Update(UpdateArgs args) { }
public class UpdateArgs { }
}
class ProgressBar : UIElement
{
public override void Update(UpdateArgs args)
{
base.Update(args);
if(args is ProgressBarUpdateArgs updateArgs)
{
Console.WriteLine(updateArgs.Progress);
}
}
public class ProgressBarUpdateArgs : UpdateArgs
{
public int Progress { get; set; }
}
}
- 使用通用
class UIElement<T> // or class UIElement<T> where T: UIElement.UpdateArgs
{
public virtual void Update(T args) { }
public class UpdateArgs { }
}
class ProgressBar : UIElement<ProgressBar.ProgressBarUpdateArgs>
{
public override void Update(ProgressBarUpdateArgs args)
{
base.Update(args);
Console.WriteLine(args.Progress);
}
public class ProgressBarUpdateArgs : UpdateArgs
{
public int Progress { get; set; }
}
}
这两种解决方案都有效,但您可以根据自己的目的选择一种。抱歉,我无法在这里简短地解释它们是如何工作的,但如果您有任何问题,请在下面发表评论w
抱歉,问题措辞不当。 我正在制作一些代表简单游戏 GUI 的 classes。 GUI 由不同的元素组成,由派生自某些共同祖先 UIElement 的 classes 表示。
class UIElement
{
public virtual void Update(UpdateArgs args) { }
public class UpdateArgs { }
}
每个元素都应包含一个 Update() 方法,但对于不同的元素,需要不同的参数(即,对于进度条,应该有一些数字表示已满,对于按钮,应该有一些布尔值来确定它是否可点击,等等在)。 所以基本上我希望能够覆盖 Update() 方法,将其参数类型更改为从原始方法的参数类型派生的类型,如下所示:
class ProgressBar : UIElement
{
public override void Update(UpdateArgs args)
{
base.Update(args);
//Set fullness
}
public class UpdateArgs : UIElement.UpdateArgs
{
double fullness;
}
}
上面的代码不起作用,因为编译器找不到合适的方法来覆盖(因为父 class 中没有 Update() 方法,它接受 ProgressBar.UpdateArgs 对象作为争论)。这是可以理解的,例如我可以实现 ProgressBar.UpdateArgs class 不是从 UIElement.UpdateArgs 派生的,这会导致错误和东西。
所以我的问题是,我怎样才能巧妙地实现上面描述的内容?是否有一些行为类似于嵌套 classes,但保证 if A : B
then A.nested : B.nested
?
我建议两种解决方案。
- 使用铸造类型
class UIElement
{
public virtual void Update(UpdateArgs args) { }
public class UpdateArgs { }
}
class ProgressBar : UIElement
{
public override void Update(UpdateArgs args)
{
base.Update(args);
if(args is ProgressBarUpdateArgs updateArgs)
{
Console.WriteLine(updateArgs.Progress);
}
}
public class ProgressBarUpdateArgs : UpdateArgs
{
public int Progress { get; set; }
}
}
- 使用通用
class UIElement<T> // or class UIElement<T> where T: UIElement.UpdateArgs
{
public virtual void Update(T args) { }
public class UpdateArgs { }
}
class ProgressBar : UIElement<ProgressBar.ProgressBarUpdateArgs>
{
public override void Update(ProgressBarUpdateArgs args)
{
base.Update(args);
Console.WriteLine(args.Progress);
}
public class ProgressBarUpdateArgs : UpdateArgs
{
public int Progress { get; set; }
}
}
这两种解决方案都有效,但您可以根据自己的目的选择一种。抱歉,我无法在这里简短地解释它们是如何工作的,但如果您有任何问题,请在下面发表评论w