我有一个接口,有一些方法
interface IFunction
{
public double y(double x);
public double yDerivative(double x);
}
我正在实施静态类。
static class TemplateFunction:IFunction
{
public static double y(double x)
{
return 0;
}
public static double yDerivative(double x)
{
return 0;
}
}
我想将这些类作为参数传递给另一个函数。
AnotherClass.callSomeFunction(TemplateFunction);
以及其他一些捕获请求的类
class AnotherClass
{
IFunction function;
public void callSomeFunction(IFunction function)
{
this.fuction = function;
}
}
嗯,它不起作用......我试图使用Type表达式,但是接缝打破了使用接口的想法。有没有人有想法,如何纠正代码?
答案 0 :(得分:5)
静态类无法实现接口,但您可以通过使类非静态和通用方法轻松克服此问题:
class AnotherClass
{
IFunction function;
public void callSomeFunction<T>()
where T: IFunction, new()
{
this.fuction = new T();
}
}
这与您想要的语法非常接近:
AnotherClass.callSomeFunction<TemplateFunction>();
但我实际上认为这种方式过于复杂并且可能会使某些人感到困惑,你应该遵循Servy的方法,这种做法更为简单:
AnotherClass.callSomeFunction(TemplateFunction.Instance);
答案 1 :(得分:2)
获取静态类来实现接口的概念方法是使用单例,即使该单例不包含任何状态:
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;
}
}
另一个选择是不使用接口,而是让您的方法接受一个或多个委托。如果你只需要一种方法就没关系,如果你有两种方法,它有时可以是好的,有时则不然。如果你有两个以上,那通常是个问题。
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);
答案 2 :(得分:0)
如何使用泛型方法来捕获您要求的类型。
像这样:
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.
}
无论如何,如果你想要这样做的原因是因为你想拥有多个实现相同方法的类,并且你想编写一个方法来根据类型调用这些方法的某个实现,那么其他解决方案可能是有序的,比如超载。
或者如果这确实是你想要做的,那么请记住,传递接口将不允许你使用我提出的方法,因为Activator需要访问Type以便它可以创建一个实例。
答案 3 :(得分:0)
你可以像All一样说并将模板功能更改为非静态,然后执行以下操作:
var anotherClass = new AnotherClass();
var templateFunction = new TemplateFunction();
anotherClass.callSomeFunction(templateFunction);