2011-02-08 63 views
15

我正在使用特定任务的.NET plattform,它是预编译的而不是OpenSource。 对于一些我需要扩展这个类的任务,而不是从它继承。我只是想添加一个方法。如何为带有类型参数约束的泛型类型编写扩展方法?

起初我想告诉你一个dummycode现有类:

public class Matrix<T> where T : new() { 
    ... 
    public T values[,]; 
    ... 
} 

我想通过以下方式扩展这个类:

public static class MatrixExtension { 
    public static T getCalcResult<T>(this Matrix<T> mat) { 
     T result = 0; 
     ... 
     return result; 
    } 
} 

我已经得到了许多谷歌这句法因此不知道链接是否正确。编译器告诉我没有错误,但最终它不起作用。最后,我想以下面的方式调用这个功能:

Matrix<int> m = new Matrix<int>(); 
... 
int aNumber = m.getCalcResult(); 

所以,任何人有一个想法?感谢您的帮助!

问候焾

+0

你觉得为什么它不工作?它是否会抛出异常? – 2011-02-08 01:52:58

+1

这是使用扩展方法的正确方法,但是由于T最初并不限于“int”,所以应该使用`T result = default(T)`而不是'T result = 0'。除此之外,您应该检查以确保您的使用声明包含您的MatrixExtension类。您可以通过直接调用`MatrixExtension.getCalcResult(m)`来检查它是否正常工作。 – 2011-02-08 01:55:05

+0

至少IDE迫使我调用这样的方法: m.getCalcResult (); 但是当我尝试编译此,我得到一个其它的错误: >“矩阵”不包含“的GetValue”的定义,并没有扩展方法“的GetValue”接受一个类型的第一个参数“矩阵”可能是发现(您是否缺少使用指令或程序集引用?) 顺便说一下,调用该方法的这种方式没有意义,因为通用参数T已被分配。 – 2011-02-08 01:59:21

回答

23

您需要在扩展方法上添加相同的类型参数约束。

这是我尝试在编译并运行了你的例子最亲密的重建,没有任何错误:

public class Matrix<T> where T : new() { 
    public T[,] values; 
} 


public static class MatrixExtension { 
    public static T getCalcResult<T>(this Matrix<T> mat) where T : new() { 
     T result = new T(); 
     return result; 
    } 
} 

class Program { 
    static void Main(string[] args) { 
     Matrix<int> m = new Matrix<int>(); 
     int aNumber = m.getCalcResult(); 
     Console.WriteLine(aNumber); //outputs "0" 
} 
-2

有你看着“装饰” ......

Sample showing Decorator patterns

装饰器允许你创建自己的属性和方法的类,而不从一个做直接推导具体的类。然后,您可以将它“应用”到任何其他物体。然后,您可以应用使用您正在尝试使用的额外方法或属性。

此示例是一个简单的快速查找出这样的例子通过构建“选项”自身附加到“汽车” ......

2

眼下,唯一的“错误”我看是这样的:

T result = 0; 

你可以修改成:

T result = default(T); 

在值类型的情况下,这将是零,因此这将是安全的。

但是,当您到达列出的“...”部分时,您会发现这很难。基本类型(int,double等)没有实现可用于计算数学的方法。这是一个long time, very highly voted request on Connect,顺便说一句。

虽然有解决方法,但它们使生活变得非常困难。与C++中的模板不同,C#的泛型实际上不支持任意类型的类型安全数学运算。