简体   繁体   English

C#传递一个Class作为参数

[英]C# Pass a Class as a parameter

I have an Interface, that has some methods 我有一个接口,有一些方法

interface IFunction
{
    public double y(double x);

    public double yDerivative(double x);
}

and I've got static classes, that are implementing it. 我有静态类,正在实现它。

static class TemplateFunction:IFunction
{
    public static double y(double x)
    {
        return 0;
    }

    public static double yDerivative(double x)
    {
        return 0;
    }
}

I want to pass this classes as a parameter to another function. 我想将这些类作为参数传递给另一个函数。

 AnotherClass.callSomeFunction(TemplateFunction);

And some other class that catches the request 以及其他一些捕获请求的类

class AnotherClass
{
    IFunction function;
    public void callSomeFunction(IFunction function)
    {
        this.fuction = function;
    }
}

Well, it doesn't work... I've tried to use the Type expression, but that seams to break the idea of using an interface. 好吧,它不起作用......我试图使用Type表达式,但是接缝打破了使用接口的想法。 Does anyone have an idea, how to correct the code? 有没有人有想法,如何纠正代码?

Static classes can't implement interfaces, but you can easily overcome this by making your class non static and a generic method: 静态类无法实现接口,但您可以通过使类非静态和通用方法轻松克服此问题:

class AnotherClass
{
    IFunction function;

    public void callSomeFunction<T>()
        where T: IFunction, new()
    {
        this.fuction = new T();
    }
}

This is much close to the syntax you wanted: 这非常接近您想要的语法:

AnotherClass.callSomeFunction<TemplateFunction>();

But I actually think that this way is too complicated and likely to confuse someone, you should follow Servy's approach which is way simpler: 但是我实际上认为这种方法太复杂了,可能会使某人感到困惑,您应该遵循Servy的方法,该方法更简单:

AnotherClass.callSomeFunction(TemplateFunction.Instance);

The conceptual way of getting a static class to implement an interface is to use a singleton, even if that singleton contains no state: 获取静态类来实现接口的概念方法是使用单例,即使该单例不包含任何状态:

public sealed class TemplateFunction : IFunction
{
    private TemplateFunction() { }
    private static TemplateFunction instance = new TemplateFunction();

    public static TemplateFunction Instance { get { return instance; } }

    public double y(double x)
    {
        return 0;
    }

    public double yDerivative(double x)
    {
        return 0;
    }
}

Another option is to just not use an interface, and instead have your method accept one or more delegates. 另一种选择是不使用接口,而是让您的方法接受一个或多个委托。 It's fine if you only need a single method, if you have two it can sometimes be okay, and sometimes not. 如果您只需要一个方法就可以,如果有两个方法就可以,有时也可以。 If you have more than two, it's usually a problem. 如果你有两个以上,这通常是一个问题。

public class AnotherClass
{
    public static void callSomeFunction(Func<double, double> y
        , Func<double, double> yDerivitive)
    {
        //store delegates for later use
    }
}

AnotherClass.callSomeFunction(TemplateFunction.y, TemplateFunction.yDerivative);

How about you use a generic method to catch the type that you are calling for. 您如何使用通用方法来捕获所需的类型。

Like this: 像这样:

public void callSomeFunction<T>()
{
    //the type is T
    //you can create an instance of T with System.Activator.CreateInstance(T) and T's methods
    //alternatively if the classes are static you can call the methods with reflection knowing only their name.
}

And anyway, if the reason you want to do this is because you want to have multiple classes that implement the same methods and you want to write a method that will call a certain implementation of those methods based on type, then other solutions might be in order, like overloading. 无论如何,如果你想要这样做的原因是因为你想要有多个实现相同方法的类,并且你想编写一个方法来调用基于类型的那些方法的某个实现,那么其他解决方案可能在顺序,像重载。

Or if indeed this is what you want to do, then keep in mind that passing an interface won't allow you to use the approach i presented you with, because the Activator needs to have access to the Type so that it can create an instance. 或者,如果这确实是你想要做的,那么请记住,传递接口将不允许你使用我提出的方法,因为Activator需要访问Type以便它可以创建一个实例。

You can do as Allon said and change the TemplateFunction to none static and then do this: 您可以按照Allon的说明进行操作,并将TemplateFunction更改为none静态,然后执行以下操作:

var anotherClass = new AnotherClass();
var templateFunction = new TemplateFunction();

anotherClass.callSomeFunction(templateFunction);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM