In C#, how do you create methods that append to variables?
I've searched around for the answer to this many times, but I don't know what this type of method is called, so my searches ended up useless, nor can I explain it to the search engine.
How do you make a method that uses the variable it is appended to as it's parameter (like "myVariable**.ToString()**)?"
.ToString() works on any variable I append it to, and uses the variable behind it as a parameter, rather than entering the parameter within the brackets... An example of what I want to do would be:
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();
}
}
I know this is kind of a stupid example, but it shows what I want to do with the "xlApp.releaseObject()".
Also... Can someone please tell me what that kind of method (or type of call, whatever it is) is called? I hate not knowing.
They're called extension methods and the only two changes that you would need to make to your method are to make it static and to add the keyword this
to inFilename:
private static void OpenExcel(this string inFileName)
{
...
}
The rest is compiler magic.
ToString is a member of System.Object so every object has this method.
There are other methods called extension methods that allow you to extend classes. They need to be static, declared in a static class. The first parameter must have the type of the class you want to extend and the keyword "this".
However in this case if you create an extension method with an "object" type you'll end up adding an extension method to every object - even those that can't be released.
All classes inherit from object, and object implements ToString(). Many classes override ToString to make it render something special. You can override ToString in your class too.
Now, if what you are talking about is extension Methods, than that is something different. If there were a class called ClassA, the I could extend it, in another class, like this:
public static string RenderString(this MyClass mc, string someotherparameter) {
return mc.ToString + someotherparameter;
}
And use it like:
classAInstance.RenderString("hello");
You're looking for Extension Methods:
http://msdn.microsoft.com/en-us/library/bb383977.aspx
These methods use the state in the class to operate on, so parameters are not always required. You implement the method in a class, and any instance of that class(the variable) can be accessed.
For example:
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() );
If you want the function to be available on ALL classes, the way ToString is, you will need to use extension methods to add it to the Object class. Because all objects inherite from Object, and ToString is a method of the Object class, then it is available on all classes. Since you did not create the Object class, the only way to add additional methods after the fact is to use extension methods.
.toString() works anywhere since all object inherit from System.Object.
In System.Object's class definition, there is a toString() method defined.
Lookup extension methods for more info
The direct answer to your question is "Extension Methods", which have been well described by Chris Pebble and linked to by other answers.
However, for your particular code example I would argue strongly against defining an extension method, because:
- There is no common base class for COM interop RCW classes, you have no choice but to extend
System.Object
. That is just plain wrong - you don't want to add a new method onto every single object in your entire app just to save a few characters typing on RCWs. - After you release the RCW, you also have to release the .NET reference. To do that, you need to pass the object parameter by reference. This is not possible with extension method syntax.
I suggest the following simple utility class instead:
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();
}
}
}
You would use it like this:
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);
}
}
The null check is useful because when your calling code gets to its finally
block and calls ComHelper.Release
, you cannot guarantee that the RCW was completely initialised in the first place.
The second method is necessary if you intend to iterate over RCW objects in C#. It explicitly avoids method overloading in order to allow the class to be called from VB.NET as well as C#.
精彩评论