Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从子类调用(静态)方法_C#_.net_Generics - Fatal编程技术网

C# 从子类调用(静态)方法

C# 从子类调用(静态)方法,c#,.net,generics,C#,.net,Generics,我创建了一个抽象类,我们称之为FooBarizable,它是两个类的父类(实践中会有更多),分别是Foo和Bar。现在,我有了一个FooBarizableManager,它管理Foo和Bar类,具体取决于他的类型。从这个FroobarizableManager,我想调用getFooBarizables()。让我们看看结构: FooBarizable.cs: public abstract class FooBarizable{ public string Name { get; set

我创建了一个抽象类,我们称之为
FooBarizable
,它是两个类的父类(实践中会有更多),分别是
Foo
Bar
。现在,我有了一个
FooBarizableManager
,它管理
Foo
Bar
类,具体取决于他的类型。从这个
FroobarizableManager
,我想调用
getFooBarizables()
。让我们看看结构:

FooBarizable.cs:

public abstract class FooBarizable{

    public string Name { get; set; }
    public static IEnumerable<FooBarizable> GetFooBars(){
        throw new NotImplementedException();
    }
}
public class Foo : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getFoos();
    }
}
public class Bar : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getBars();
    }
}
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);
    }

    ...

}
公共抽象类FooBarizable{
公共字符串名称{get;set;}
公共静态IEnumerable GetFooBars(){
抛出新的NotImplementedException();
}
}
Foo.cs:

public abstract class FooBarizable{

    public string Name { get; set; }
    public static IEnumerable<FooBarizable> GetFooBars(){
        throw new NotImplementedException();
    }
}
public class Foo : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getFoos();
    }
}
public class Bar : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getBars();
    }
}
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);
    }

    ...

}
公共类Foo:FooBarizable{
公共静态IEnumerable GetFooBars(){
返回API.getFoos();
}
}
Bar.cs:

public abstract class FooBarizable{

    public string Name { get; set; }
    public static IEnumerable<FooBarizable> GetFooBars(){
        throw new NotImplementedException();
    }
}
public class Foo : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getFoos();
    }
}
public class Bar : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getBars();
    }
}
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);
    }

    ...

}
公共类栏:FooBarizable{
公共静态IEnumerable GetFooBars(){
返回API.getbar();
}
}
FooBarizableManager.cs:

public abstract class FooBarizable{

    public string Name { get; set; }
    public static IEnumerable<FooBarizable> GetFooBars(){
        throw new NotImplementedException();
    }
}
public class Foo : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getFoos();
    }
}
public class Bar : FooBarizable{

    public static IEnumerable<FooBarizable> GetFooBars(){
        return API.getBars();
    }
}
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);
    }

    ...

}
公共类FooBarizableManager{
私有类型;
公共餐饮管理器(t型){
this.type=\u t;
}
公共空间showFooBarizables(){
MethodInfo方法=type.GetMethod(“GetFooBars”);
IEnumerable FooBars=(IEnumerable)方法.invoke(null,null);
表演(食物棒);
}
...
}
因此,我的问题是,我希望使用类型从管理器获取对象集合,但强制子类实现
getFooBars()
方法

我面临的问题:

  • .Net不允许定义静态抽象方法,因此我无法创建
    公共静态抽象IEnumerable GetFooBars()
    并强制子类来实现它

  • 实现的方式不会在子类中强制实现该方法,但我尝试至少抛出一个
    NotImplementedException
    。问题是当我调用
    MethodInfo method=type.GetMethod(“GetFooBars”)
    在管理器中,如果子类未实现该方法,
    method
    为null,而调用
    NullPointerException

  • 我试图创建一个实例方法而不是静态的静态方法,它解决了强制问题,因为子类必须实现它,但在我看来,创建一个不必要的实例来调用一个方法是不正确的

因此,是否有任何解决方案强制子类实现
getFooBar()
方法?
如果没有,如何抛出
NotImplementedException
而不是
NullPointerException

有没有办法强制子类实现
getFooBar()
方法

不适用于静态方法。静态方法绑定到特定的类,因此它们不能被继承,也不能抽象或虚拟

如果要使该方法具有多态性,则必须是实例方法

如何抛出
NotImplementedException
而不是
NullPointerException

得到该异常的结果是,该类型没有
GetFooBars
方法,因此
method
null
。因此,您可以先检查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);
}
public void showFooBarizables(){
MethodInfo方法=type.GetMethod(“GetFooBars”);
if(方法==null)
抛出新的NotImplementedException();
IEnumerable FooBars=(IEnumerable)方法.invoke(null,null);
表演(食物棒);
}
但是抛出该异常有点误导,因为调用方可能认为
showFooBarizables
方法没有实现,而不是底层的
GetFooBars


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

无法通过任何形式的继承或多态性强制执行静态方法,但一个潜在的解决方法是为
FooBarizable
实现扩展方法,这样任何继承它的类都可以访问扩展

静态方法与类的对象(实例)无关,它始终与类本身相关

强制实现方法的一种方法是使用接口。 另一种方式,我想这就是你想要的,因为这个方法在不同的实例中会有不同的行为,那就是使用抽象方法

public abstract class AbstractClass 
{
    public abstract int MustIMplementThis(string param1);
}

public class ChildClass : AbstractClass
{

    public override int MustIMplementThis(string param1)
    {
        throw new NotImplementedException();
    }
}

从AbstracClass继承的所有类都必须实现父类上列出的方法。

当然.NET不允许您编写虚拟静态方法:)

虚拟方法的全部要点是,当您对类型为
Derived
的实例调用
Base.DoSomething
方法时,执行的是
Derived.DoSomething
中的代码。但这意味着您需要实例知道它的实际运行时类型,以便您知道实际应该执行什么方法

典型的替代方法是使用某种形式的工厂接口。也就是说,不必查询
Foo.GetFooBars
Bar.GetFooBars
,您将获得相关实例类型的提供者实例,例如
Fooizer.GetFooBars
Barizer.GetFooBars
,其中
Fooizer
Barizer
都实现
IFooBarProvider
GetFooBars
不适合
FooBarizable
界面,因为它不属于该界面。面向对象设计、责任、替代原则以及所有这些:)

那么,如果你