从子类调用(静态)方法

Jos*_*ose 3 .net c# generics

我创建了一个抽象类,我们称之为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

D S*_*ley 5

有什么解决方案可以强制子类实现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.

由于这些方法似乎是工厂方法,也许您需要为每种类型提供一个工厂?您似乎正在尝试使用泛型来替代重载。工厂方法通常不是通用的,因为它们必须针对每种类型具有不同的逻辑。您可以创建一个包含通用代码的“基本”工厂,然后为每个特定类型对该工厂进行子类化。