在基类方法中引用继承类?
Posted
技术标签:
【中文标题】在基类方法中引用继承类?【英文标题】:Reference inheriting class in base class method? 【发布时间】:2021-11-17 22:20:31 【问题描述】:我正在寻找在(抽象)基类中提供方法的最佳方式,所有继承类都应该能够使用该方法。 此方法需要引用继承类型的字段和属性。 有没有办法提供这样一个不需要我的原型方法:
传递对每个有问题的继承实例的引用 在每个继承类上实现一个方法,它将对自身的引用传递给基类的方法 为实现类编写扩展方法上述所有工作,但在他们自己的方式似乎有些不方便和不优雅。
下面是一个例子,我实现了上面三个引用继承类的方法:
using System;
namespace Test
public abstract class BaseClass
public void ReferenceInheriting(object InheritingInstance)
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + InheritingInstance.GetType().Name);
public class Inheriting : BaseClass
public void MakeUseOfBaseClassImplementation()
base.ReferenceInheriting(this);
public static class Extensions
public static void BeAvailableForAllImplementing(this BaseClass Inh)
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + Inh.GetType().Name);
class program
public static void Main(string[] args)
Inheriting inh = new Inheriting();
Console.WriteLine("Method 1: Calling the inherited method from an inheriting instance, passing a reference to the instance:");
inh.ReferenceInheriting(inh);
Console.WriteLine("Method 2: Implementing call to the base class's method in own class:");
inh.MakeUseOfBaseClassImplementation();
Console.WriteLine("Method 3: Extension method for all implementing classes:");
inh.BeAvailableForAllImplementing();
这三种方法都产生相同的输出,但都有缺点。 缺少解析来电者信息,有没有其他方法可以做到这一点? 当然这没什么大不了的,但我有兴趣让这个方法尽可能地对用户友好,无论是实现继承还是调用。
谢谢!
【问题讨论】:
为什么要在这里使用反射?如果BaseClass
有合法用途,为什么不声明 getMe
?
附带说明:如果您遵循正常的命名约定,即使对于示例代码,它也会很有帮助。对于阅读问题或试图回答您的人来说,任何非常规的内容都会分散您的注意力。
@JonSkeet 您具体指的是命名约定的哪些方面?当然,名字可能有点长,但我认为他们描述了我对他们的期望,好吧
@BenPhilipp:reflectInheriting
应该是 ReflectInheriting
,getMe
应该是 GetMe
,等等。我认为问题不在于长度,而在于大小写。它也让我有点失望。
@ThomasBonini 哦!我看到了
【参考方案1】:
你不需要这些。
这个:
public void reflectInheriting(object inheritingInstance)
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + inheritingInstance.GetType().Name);
FieldInfo fi = inheritingInstance.GetType().GetField("getMe");
Console.WriteLine(fi.GetValue(inheritingInstance));
可以简单地改写为:
public void reflectInheriting()
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + this.GetType().Name);
FieldInfo fi = this.GetType().GetField("getMe");
Console.WriteLine(fi.GetValue(this));
这就是你所需要的。
C# 保存对象的实际底层类型,不管它是如何转换的,所以即使在 BaseClass
内部,this.GetType()
也将是 Inheriting
。
证明没有任何变化的程序输出:
方法一:从继承的实例调用继承的方法,传递对实例的引用:
做特定于继承类或其实例的事情:继承
在 BaseClass 中使用我
方法二:在自己的类中实现对基类方法的调用:
做特定于继承类或其实例的事情: 继承
在 BaseClass 中使用我
方法3:所有实现类的扩展方法:
做特定于继承类或其实例的事情:继承
在 BaseClass 中使用我
【讨论】:
什么...这是如此基本的行为,我不敢相信我不知道它是如何工作的! ?♂️谢谢!【参考方案2】:您可以使用反射,但这是一种最后的武器。在派生类中访问属性或方法的惯用方式是在基类中将其抽象化。
public abstract class BaseClass
public void GetInheriting()
Console.WriteLine("GetMe is: 0", this.GetMe);
protected abstract string GetMe get;
public class Inheriting : BaseClass
protected override string GetMe => "Use me in BaseClass";
public void MakeUseOfBaseClassImplementation()
base.GetInheriting();
public class Program
static public void Main()
var o = new Inheriting();
o.MakeUseOfBaseClassImplementation();
Link to Fiddle
输出:
GetMe is: Use me in BaseClass
【讨论】:
反射是我首先想要实现的一部分。请注意,我并没有尝试使用反射来获取对该类的引用,并且它不用于尝试回答问题。实际实现为所有继承类提供自定义功能,需要从中获取属性和字段 很公平......当有人提出问题时,很难说他们知道多少,不知道多少,我不想错过“正常”的方法。我相信您有充分的理由使用反射。 很抱歉造成了一些混乱,我想我会让我的部分代码作为使用继承类的示例,但似乎这是一个坏主意?反射现在从我的问题中删除。感谢您的时间和投入,对不起,我在试图说明我的问题时不太清楚^^以上是关于在基类方法中引用继承类?的主要内容,如果未能解决你的问题,请参考以下文章