繁体   English   中英

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

[英]In C#, how do you create methods that append to variables?

我已经搜索了很多次答案,但是我不知道这种方法叫什么,所以我的搜索最终无用,也无法向搜索引擎解释。

您如何制作一个使用附加到变量中作为参数的方法(例如“ 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()”进行的操作。

另外...有人可以告诉我调用那种方法(或调用类型,无论调用什么)吗? 我不知道。

它们被称为扩展方法 ,您只需对方法进行两项更改即可使其静态化并将关键字this添加到inFilename中:

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

剩下的就是编译器魔术了。

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

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

但是,在这种情况下,如果使用“对象”类型创建扩展方法,则最终将向每个对象(甚至是那些无法发布的对象)添加一个扩展方法。

所有类都从object继承,而object实现ToString()。 许多类重写ToString以使其呈现特殊的外观。 您也可以在类中重写ToString。

现在,如果您要谈论的是扩展方法,那将有所不同。 如果有一个叫做ClassA的类,我可以将它扩展到另一个类中,如下所示:

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

并像这样使用它:

classAInstance.RenderString("hello");

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

例如:

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() );

如果希望该函数在ToClass的所有类中都可用,则需要使用扩展方法将其添加到Object类。 因为所有对象都继承自Object,并且ToString是Object类的方法,所以它在所有类上均可用。 由于您没有创建Object类,因此添加其他方法的唯一方法是使用扩展方法。

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

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

查找扩展方法以获取更多信息

您问题的直接答案是“扩展方法”,该方法已由Chris Pebble很好地描述,并与其他答案相关联。

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

  1. COM互操作RCW类没有通用的基类,只能扩展System.Object 这完全是错误的-您不想在整个应用程序中的每个对象上添加新方法,只是为了节省在RCW上键入的几个字符。
  2. 释放RCW之后,还必须释放.NET参考。 为此,您需要通过引用传递对象参数。 使用扩展方法语法是不可能的。

我建议使用以下简单的实用程序类:

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#调用该类。

暂无
暂无

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

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