我创建了一个抽象类,我们称之为FooBarizable,它是 2 个类的父类(更多在实践中),Foo并且Bar. 现在,我有一个可以根据他的类型FooBarizableManager进行管理Foo和上课的人。Bar由此FroobarizableManager,我想打电话getFooBarizables()。我们看一下结构:
FooBarized.cs:
public abstract class FooBarizable{
public string Name { get; set; }
public static IEnumerable<FooBarizable> GetFooBars(){
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
Foo.cs:
public class Foo : FooBarizable{
public static IEnumerable<FooBarizable> GetFooBars(){
return API.getFoos();
}
}
Run Code Online (Sandbox Code Playgroud)
酒吧.cs:
public class Bar : FooBarizable{
public static IEnumerable<FooBarizable> GetFooBars(){
return API.getBars();
}
}
Run Code Online (Sandbox Code Playgroud)
FooBarizedManager.cs:
public class FooBarizableManager {
private Type type;
public FooBarizableManager(Type _t){
this.type = _t;
}
public void showFooBarizables(){
MethodInfo method = type.GetMethod("GetFooBars");
IEnumerable<FooBarizable> FooBars = (IEnumerable<FooBarizable>)method.invoke(null, null);
show(FooBars);
}
...
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是我想使用类型从管理器获取对象集合,但强制子类实现getFooBars()方法。
我遇到的问题:
.Net 不允许定义静态抽象方法,因此我无法创建public static abstract IEnumerable<FooBarizable> GetFooBars()和强制子类来实现它。
实现的方式并不强制在子类中实现该方法,但我尝试至少抛出一个NotImplementedException. 问题是,当我调用MethodInfo method = type.GetMethod("GetFooBars");管理器时,如果子类没有实现该方法,method则为 null,并被NullPointerException调用。
我尝试创建一个实例方法而不是静态方法,它解决了强制问题,因为子类必须实现它,但对我来说创建不必要的实例来调用方法似乎并不正确。
那么,有没有办法强制子类实现getFooBar()方法呢?如果没有,我该如何抛出NotImplementedException代替NullPointerException?
有什么解决方案可以强制子类实现
getFooBar()方法吗?
不适用于静态方法。静态方法与特定的类绑定,因此它们不能被继承,也不能抽象或虚拟。
如果你想让方法多态,它需要是一个实例方法。
我怎样才能扔掉
NotImplementedException而不是NullPointerException
您得到该异常的结果是因为该类型没有方法,GetFooBars因此method也是如此null。所以你可以先检查是否为空:
public void showFooBarizables(){
MethodInfo method = type.GetMethod("GetFooBars");
if(method == null)
throw new NotImplementedException();
IEnumerable<FooBarizable> FooBars = (IEnumerable<FooBarizable>)method.invoke(null, null);
show(FooBars);
}
Run Code Online (Sandbox Code Playgroud)
但是抛出该异常有点误导,因为调用者可能认为该showFooBarizables方法未实现,而不是底层的GetFooBars.
由于这些方法似乎是工厂方法,也许您需要为每种类型提供一个工厂?您似乎正在尝试使用泛型来替代重载。工厂方法通常不是通用的,因为它们必须针对每种类型具有不同的逻辑。您可以创建一个包含通用代码的“基本”工厂,然后为每个特定类型对该工厂进行子类化。