C# 在C中为抽象类的子类型实现重载方法#
我是C#新手,我真的很想为定义的抽象类的每个子类型实现特定的不同方法,但是我很难弄清楚如何让编译器正确地完成这项工作。例如:C# 在C中为抽象类的子类型实现重载方法#,c#,overloading,C#,Overloading,我是C#新手,我真的很想为定义的抽象类的每个子类型实现特定的不同方法,但是我很难弄清楚如何让编译器正确地完成这项工作。例如: public abstract class MasterClass { } public class SubClass1 : MasterClass { } public class SubClass2 : MasterClass { } public class SeparateClass { public void HandleMasterClass(Mas
public abstract class MasterClass { }
public class SubClass1 : MasterClass { }
public class SubClass2 : MasterClass { }
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
SpecificMethod(item)
}
public void SpecificMethod(SubClass1 item)
{
//something specific to SubClass1
}
public void SpecificMethod(SubClass2 item)
{
//something specific to SubClass2
}
}
public abstract class MasterClass
{
public abstract int Stuff();
// New method that all subclasses will have to implement.
// You could also have this be virtual with an implementation
// for Visit(MasterClass) to provider a default behavior.
public abstract void Accept(IVisitor visitor);
}
public class SubClass1 : MasterClass
{
public override int Stuff() => 0;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public class SubClass2 : MasterClass
{
public override int Stuff() => 1;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public interface IVisitor
{
// Need an overload for all subclasses.
void Visit(SubClass1 item);
void Visit(SubClass2 item);
}
public class MasterClassDictionary
{
public Dictionary<SubClass1, int> subClass1Dict { get; } = new Dictionary<SubClass1, int>();
public Dictionary<SubClass2, int> subClass2Dict { get; } = new Dictionary<SubClass2, int>();
public void Add(MasterClass item)
{
int val = item.Stuff();
var visitor = new Visitor(this, val);
item.Accept(visitor);
}
void AddToDict(SubClass1 item, int val) { subClass1Dict[item] = val; }
void AddToDict(SubClass2 item, int val) { subClass2Dict[item] = val; }
// Provides the visitor implementation that holds any state that might
// be needed and dispatches to the appropriate method.
private class Visitor : IVisitor
{
private MasterClassDictionary _parent;
private int _value;
public Visitor(MasterClassDictionary parent, int val)
{
_parent = parent;
_value = val;
}
public void Visit(SubClass1 item) => _parent.AddToDict(item, _value);
public void Visit(SubClass2 item) => _parent.AddToDict(item, _value);
}
}
这会在编译时返回一个错误,因为没有SpecificMethod(MasterClass项)
,但我真正想要的是它根据子类选择正确的方法,而不必编写单独的HandleMasterClass(subclass 1项)
和HandleMasterClass(subclass 2项)
方法,因为它们基本上是相同的代码
我的主要语言是Jula,所以我非常习惯于依赖多个分派来做这种事情。我知道它在C#中可能不惯用,那么我该如何做得更好呢
编辑:显示方法不是自由的,而是独立类的一部分
这里有一个更好的具体例子
public abstract class MasterClass { public abstract int Stuff(); }
public class SubClass1 : MasterClass
{
public override int Stuff() { /*calculate and return an int*/ }
}
public class SubClass2 : MasterClass
{
public override int Stuff() { /*calculate and return an int*/ }
}
public class MasterClassDictionary
{
public Dictionary<int, SubClass1> subClass1Dict{get;} = new Dictionary<int, SubClass1>()
public Dictionary<int, SubClass2> subClass2Dict{get;} = new Dictionary<int, SubClass2>()
public void Add(MasterClass item)
{
int val = item.Stuff();
AddToDict(val, item);
}
void AddToDict(int val, SubClass1 item) { subClass1Dict[val] = item; }
void AddToDict(int val, SubClass2 item) { subClass2Dict[val] = item; }
}
public抽象类MasterClass{public abstract int Stuff();}
公共类子类1:主类
{
public override int Stuff(){/*计算并返回int*/}
}
公共类子类2:主类
{
public override int Stuff(){/*计算并返回int*/}
}
公共类MasterClassDictionary
{
公共字典子类1dict{get;}=newdictionary()
公共字典子类2dict{get;}=newdictionary()
公共作废添加(MasterClass项目)
{
int val=item.Stuff();
AddToDict(val,项目);
}
void AddToDict(int-val,子类1项){subClass1Dict[val]=item;}
void AddToDict(int-val,子类2项){subClass2Dict[val]=item;}
}
我知道这是一个有点做作的示例,但它与我尝试做的类似。通常,您希望将特定于类的代码放在该类中。因此,您的抽象类将使用关键字定义特定的方法签名,而实现将位于类内部,使用关键字,如下所示:
public abstract class MasterClass {
public abstract void SpecificMethod();
}
public class SubClass1 : MasterClass {
public override void SpecificMethod()
{
//something specific to SubClass1
// use the this keyword to access the instance
}
}
public class SubClass2 : MasterClass {
public override void SpecificMethod()
{
//something specific to SubClass2
// use the this keyword to access the instance
}
}
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
item.SpecificMethod()
}
}
根据您的评论,这是我在您的具体示例中实现的方法,尽管它可能不符合您的要求:
public class MasterClassDictionary
{
public Dictionary<int, SubClass1> subClass1Dict{get;} = new Dictionary<int, SubClass1>()
public Dictionary<int, SubClass2> subClass2Dict{get;} = new Dictionary<int, SubClass2>()
public void Add(MasterClass item)
{
int val = item.Stuff();
if (item is SubClass1)
{
subClass1Dict[val] = item;
}
if (item is SubClass2)
{
subClass2Dict[val] = item;
}
}
}
公共类MasterClassDictionary
{
公共字典子类1dict{get;}=newdictionary()
公共字典子类2dict{get;}=newdictionary()
公共作废添加(MasterClass项目)
{
int val=item.Stuff();
如果(项目为子类1)
{
子类1DICT[val]=项目;
}
如果(项目为子类2)
{
子类2DICT[val]=项目;
}
}
}
这种情况下的标准设计模式是。这是一个有点复杂的模式,但基本思想是子类知道它们是什么类型,因此我们将通过一个名为“Accept”的虚拟方法调用它们,它们将自己传递回作为引用。它们回调的方法称为Visit,并对所有可能的子类重载。以下是您的示例的实现:
public abstract class MasterClass { }
public class SubClass1 : MasterClass { }
public class SubClass2 : MasterClass { }
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
SpecificMethod(item)
}
public void SpecificMethod(SubClass1 item)
{
//something specific to SubClass1
}
public void SpecificMethod(SubClass2 item)
{
//something specific to SubClass2
}
}
public abstract class MasterClass
{
public abstract int Stuff();
// New method that all subclasses will have to implement.
// You could also have this be virtual with an implementation
// for Visit(MasterClass) to provider a default behavior.
public abstract void Accept(IVisitor visitor);
}
public class SubClass1 : MasterClass
{
public override int Stuff() => 0;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public class SubClass2 : MasterClass
{
public override int Stuff() => 1;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public interface IVisitor
{
// Need an overload for all subclasses.
void Visit(SubClass1 item);
void Visit(SubClass2 item);
}
public class MasterClassDictionary
{
public Dictionary<SubClass1, int> subClass1Dict { get; } = new Dictionary<SubClass1, int>();
public Dictionary<SubClass2, int> subClass2Dict { get; } = new Dictionary<SubClass2, int>();
public void Add(MasterClass item)
{
int val = item.Stuff();
var visitor = new Visitor(this, val);
item.Accept(visitor);
}
void AddToDict(SubClass1 item, int val) { subClass1Dict[item] = val; }
void AddToDict(SubClass2 item, int val) { subClass2Dict[item] = val; }
// Provides the visitor implementation that holds any state that might
// be needed and dispatches to the appropriate method.
private class Visitor : IVisitor
{
private MasterClassDictionary _parent;
private int _value;
public Visitor(MasterClassDictionary parent, int val)
{
_parent = parent;
_value = val;
}
public void Visit(SubClass1 item) => _parent.AddToDict(item, _value);
public void Visit(SubClass2 item) => _parent.AddToDict(item, _value);
}
}
您可以使一个方法接受“主类”,并使用原样检查或其他方法。你也可以在HandleMaster类中做同样的事情,我没有提到,但是这些方法是在一个单独的类中,为那些被编辑的内容做一些事情,以表明我个人喜欢这样做,因为我在阅读别人的帖子时通常不看编辑历史记录,而编辑注释会在上下文中添加像你这样的评论。可以将其视为解释为什么要编辑某些内容的代码注释,而不仅仅是editOne解决方案将项转换为动态(SpecificMethod((dynamic)item))。不过我更喜欢强类型解决方案。另一种说法是抽象基类不应该知道或引用它们的子类。无法保存我的编辑(时间不够长)
overrides
关键字应该是override
我添加了一个更具体的示例来说明我为什么不这么做。您能告诉我您是否仍然会采用这种方法吗?谢谢,@GreggL,完全没有采用这种方法。@stords,我想在您的具体示例中,我可能只需要在MasterClassDictionary
的Add
方法中使用关键字进行一些类型检查,以确保项目最终位于正确的词典中。在不了解您的具体需求的情况下,很难提出进一步的建议。这是完美的。我正试图编写对性能非常敏感的代码(这是首先使用C#而不是Julia或Python的原因),因此我尝试将尽可能多的工作留给编译器,同时尽可能节省自己的键入工作。我喜欢普通的IVisitorinterface@stords如果这是对性能非常敏感的代码,我可能希望对这两种方法进行基准测试。visitor模式显示进行了交换机没有的分配。根据场景的不同,内存压力可能是一个更大的问题,但这可以通过共享和重用访问者对象来缓解。