代码之家  ›  专栏  ›  技术社区  ›  Sivvy

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

c#
  •  1
  • Sivvy  · 技术社区  · 16 年前

    如何创建一个方法,将附加的变量用作参数(如“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();
            }
        }
    

    也。。。有人能告诉我这种方法(或调用类型,不管它是什么)被调用吗?我讨厌不知道。

    7 回复  |  直到 16 年前
        1
  •  11
  •   Chris Van Opstal    16 年前

    他们被称为 extension methods this 要填充,请执行以下操作:

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

    剩下的就是编译器的魔力。

        2
  •  8
  •   Matt Breckon    16 年前

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

    然而,在这种情况下,如果您创建了一个具有“object”类型的扩展方法,那么最终将为每个对象添加一个扩展方法——即使是那些无法发布的对象。

        3
  •  2
  •   Josh Pearce    16 年前

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

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

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

    然后像这样使用它:

    classAInstance.RenderString("hello");
    
        5
  •  1
  •   AaronLS    16 年前

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

    例如:

    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,并且ToString是Object类的一个方法,所以它在所有类上都可用。由于没有创建对象类,因此在创建对象类之后添加其他方法的唯一方法是使用扩展方法。

        6
  •  1
  •   curtisk    16 年前

    .toString()可以在任何位置工作,因为所有对象都继承自System.object。

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

    查找 extension methods

        7
  •  1
  •   Christian Hayter    16 年前

    你的问题的直接答案是“扩展方法”,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一开始就已完全初始化。