在C#中,如何创建附加到变量的方法?

时间:2009-11-23 18:11:21

标签: c#

我已经多次搜索过这个问题的答案,但我不知道这种方法被调用了什么,所以我的搜索结果没用,我也无法向搜索引擎解释。

如何创建一个方法,使用它附加的变量作为参数(如“myVariable **。ToString()**)?”

.ToString()适用于我追加的任何变量,并使用它后面的变量作为参数,而不是在括号中输入参数......我想做的一个例子是:

    private void OpenExcel(string inFileName)
    {
        Excel.Application xlApp = new Excel.ApplicationClass();
        Excel.Workbook xlBook = xlApp.Workbooks.Open(inFileName
            , Type.Missing, Type.Missing, Type.Missing, Type.Missing
            , Type.Missing, Type.Missing, Type.Missing, Type.Missing
            , Type.Missing, Type.Missing, Type.Missing, Type.Missing
            , Type.Missing, Type.Missing);
        Excel.Worksheet xlSheet = (Excel.Worksheet)xlBook.Worksheets[1];

        xlApp.Quit();
        xlApp.releaseObject();
    }

    private void releaseObject(object obj)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
            obj = null;
        }
        catch (Exception)
        {
            obj = null;
        }
        finally
        {
            GC.Collect();
        }
    }

我知道这是一个愚蠢的例子,但它显示了我想用“xlApp.releaseObject()”做什么。

另外......有人可以告诉我这种方法(或呼叫类型,不管是什么类型)是什么?我讨厌不知道。

7 个答案:

答案 0 :(得分:11)

它们被称为extension methods,您需要对方法进行的唯一两项更改是将其设置为静态并将关键字this添加到inFilename:

private static void OpenExcel(this string inFileName)
{
     ...
}

其余的是编译魔术。

答案 1 :(得分:8)

ToString是System.Object的成员,因此每个对象都有此方法。

还有其他方法称为扩展方法,允许您扩展类。它们需要是静态的,在静态类中声明。第一个参数必须具有要扩展的类的类型以及关键字“this”。

但是在这种情况下,如果你创建一个带有“object”类型的扩展方法,你最终会为每个对象添加一个扩展方法 - 即使是那些无法释放的对象。

答案 2 :(得分:2)

所有类都继承自object,而object实现ToString()。许多类重写ToString以使其呈现特殊的东西。您也可以在类中覆盖ToString。

现在,如果你所谈论的是扩展方法,那就不同了。如果有一个名为ClassA的类,我可以在另一个类中扩展它,如下所示:

public static string RenderString(this MyClass mc, string someotherparameter) {
    return mc.ToString + someotherparameter;
}

并使用它:

classAInstance.RenderString("hello");

答案 3 :(得分:1)

答案 4 :(得分:1)

这些方法使用类中的状态进行操作,因此并不总是需要参数。您可以在类中实现该方法,并且可以访问该类的任何实例(变量)。

例如:

class Name
{
  public string FirstName;
  public string LastName;

  public string GetFullName()
  {
     return this.FirstName + this.LastName; 
  }

}

//code demonstrating usage of class:
Name someName = new Name();
someName.FirstName = "Aaron";
someName.LastName = "Smith";

//no parameter is needed for the GetFullName method because
//it will access the member variables
Console.WriteLine( someName.GetFullName() );

如果希望函数在所有类上都可用,就像ToString一样,您将需要使用扩展方法将它添加到Object类。因为所有对象都继承自Object,而ToString是Object类的方法,所以它在所有类上都可用。由于您没有创建Object类,因此在事后添加其他方法的唯一方法是使用扩展方法。

答案 5 :(得分:1)

.toString()可以在任何地方使用,因为所有对象都继承自System.Object。

在System.Object的类定义中,定义了一个toString()方法。

查找extension methods了解更多信息

答案 6 :(得分:1)

您的问题的直接答案是“扩展方法”,这些方法已由Chris Pebble充分描述并与其他答案相关联。

但是,对于您的特定代码示例,我强烈反对 反对 定义扩展方法,因为:

  1. COM interop RCW类有 no 公共基类,你别无选择,只能扩展System.Object。这是完全错误的 - 您不希望在整个应用程序中的每个对象上添加一个新方法,只是为了节省在RCW上键入的几个字符。
  2. 发布RCW后,还必须发布.NET引用。为此,您需要通过引用传递object参数。扩展方法语法无法做到这一点。
  3. 我建议使用以下简单的实用程序类:

    public static class ComHelper {
        // Release normal RCW objects.
        public static void Release(ref object obj) {
            if (obj == null) {
                return;
            }
            try {
                Marshal.FinalReleaseComObject(obj);
                obj = null;
            } catch (Exception) {
                obj = null;
            } finally {
                GC.Collect();
            }
        }
        // Release "foreach" iterator RCW objects (which are immutable).
        public static void ReleaseIterator(object obj) {
            if (obj == null) {
                return;
            }
            try {
                Marshal.FinalReleaseComObject(obj);
            } finally {
                GC.Collect();
            }
        }
    }
    

    您可以这样使用它:

    private void OpenExcel(string inFileName) {
        Excel.Application xlApp = null;
        try {
            xlApp = new Excel.ApplicationClass();
            Excel.Workbook xlBook = xlApp.Workbooks.Open(inFileName
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing);
            Excel.Worksheet xlSheet = (Excel.Worksheet)xlBook.Worksheets[1];
            xlApp.Quit();
        } finally {
            ComHelper.Release(ref xlApp);
        }
    }
    

    空检查非常有用,因为当您的调用代码到达其finally块并调用ComHelper.Release时,您无法保证RCW首先完全初始化。

    如果您打算在C#中迭代RCW对象,则需要第二种方法。它明确地避免了方法重载,以便允许从VB.NET和C#中调用类。