我正在开发一种通用方法,该方法接受参数,其类型应从给定接口的通用类型参数推断出来。我想实现类似于以下(非编译)代码的编译时类型安全:
/// <summary>
/// Applies the specified IOperation to this PradResult.
/// </summary>
/// <typeparam name="T">The type of the operation to apply.</typeparam>
/// <param name="p1">The first parameter for the operation.</param>
/// <param name="p2">The second parameter for the operation.</param>
/// <param name="parameters">Additional parameters for the operation.</param>
/// <returns>A new PradResult after applying the operation.</returns>
public PradResult Then<T>(T.Args[0] p1, T.Args[1] p2, params object[] parameters)
where T : IPradOperation<,>, new()
{
var opType = typeof(T);
IOperation op = (IOperation)Activator.CreateInstance(opType);
var forwardMethod = opType.GetMethod("Forward");
var forwardParams = parameters.Prepend(p2).Prepend(p1);
var length = parameters.Length;
...
}
这个想法是,p1 和 p2 参数应该根据 T 实现的 IPradOperation 接口的第一个和第二个泛型类型参数自动推断其类型。
但是,据我所知,C# 目前不直接支持此语法。是否有任何解决方法或替代模式可以用来在我的泛型方法中实现这种编译时类型推断?
我希望 Then 方法尽可能用户友好,这样他们就不必指定 'T.Args[0]' 和 'T.Args[1]' 的类型,在我的示例中是“矩阵”类型。
为了完整起见,这里是 IPradOperation 接口:
/// <summary>
/// A PRAD Operation.
/// </summary>
/// <typeparam name="T">The first parameter to the forward function.</typeparam>
/// <typeparam name="TR">The return type of the forward function.</typeparam>
public interface IPradOperation<T, TR>
{
}
界面的使用方式如下:
public class AmplifiedSigmoidOperation : Operation, IPradOperation<Matrix, Matrix>
{
...
/// <summary>
/// The forward pass of the operation.
/// </summary>
/// <param name="input">The input for the operation.</param>
/// <returns>The output for the operation.</returns>
public Matrix Forward(Matrix input)
{
this.input = input;
int numRows = input.Length;
int numCols = input[0].Length;
this.Output = new Matrix(numRows, numCols);
for (int i = 0; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
this.Output[i][j] = 1.0f / (1.0f + PradMath.Pow(PradMath.PI - 2, -input[i][j]));
}
}
return this.Output;
}
...
}
这是一种解决方法。定义:
interface IPradOperations<U, V>
{
void Forward(U u, V v);
}
class PradOperations : IPradOperations<int, string>
{
public void Forward(int u, string v)
{
// do something
}
}
static class Extensions
{
static public PradResult Then<T, U, V>(this T t, U p1, V p2, params object[] parameters)
where T : IPradOperations<U, V>, new()
{
// ....
}
}
其用途:
var operations = new PradOperations();
var result = operations.Then(1, "2", 3, 4, 5, 6, 7, 8, 9, 10);