2011-01-26 9 views
6

エクステンションメソッドが新しく、できることを模索しています。C#エクステンションメソッド - 呼び出し元オブジェクトを返す

特定の割り当てを行わずに呼び出し元オブジェクトに出力を割り当てることは可能ですか?具体的に割り当てずに"Hello World! Extended!"をもたらすことがfoo.ExtensionTest()を取得する方法がある...次の例で

public static string ExtensionTest(this string input) 
{ 
    return input + " Extended!"; 
} 

...

var foo = "Hello World!"; 

var foo2 = foo.ExtensionTest(); // foo2 = "Hello World! Extended!" 

foo.ExtensionTest(); // foo = "Hello World!" 

foo = foo.ExtensionTest(); // foo = "Hello World! Extended!" 

:ここ

を説明する簡単な例であります foo = foo.ExtensionTest()

+0

サウンズ'foo.Extension();'のようになります。残念ながら、言語には現在この機能がありません。おそらく言語デザイナーに推薦する何か? :)個人的には、私はそれを望んでいません。 – Ani

+3

@アニ:ハハ、いや!ああ、あなたは*虐待*が起こると想像できますか? 'string bar = foo; foo.DoSomething(); Console.WriteLine(ReferenceEquals(bar、foo)); '...(出力:' False'、開発者:* WHAAAT?!?*) –

+1

@ダンタオ:そうです。すべてのヒントは静的メソッドに属します。 – Ani

答えて

13

いいえ、しかし、動作しない理由は、文字列の不変性と、拡張メソッドとは関係ありません。

public class SomeClass 
{ 
    public int Value {get; set;} 
} 

と拡張方法:.NETで

var someClass = new SomeClass{ Value = 1 }; 
someClass.DoIt(); 

Console.WriteLine(someClass.Value); //prints "2" 
+0

私は実際にXmlNodesとXmlDocumentsでこれをやりたがっています。これはもっと簡単なことでした(私は思っていました)。 – Shevek

5

あなたが見ているのは、文字列が不変であるためです。

いずれにしても、オブジェクトを変更する場合は、にはが割り当てられています。

+0

私は実際にXmlNodesとXmlDocumentsでこれをやりたがっています。これはもっと簡単なことでした(私は思っていました)。 – Shevek

4

'this'パラメータは、参照渡しではなく値渡しされます。だから、あなたの拡張メソッドで 'this'によってエイリアスされている呼び出し側プログラムの変数を変更することはできません。

1

番号の文字列です:

public static void DoIt(this SomeClass someClass) 
{ 
    someClass.Value++; 
} 

はの効果を持つことになりますが、クラスを持っていた代わりに、場合

不変。すべてのpublic Stringメソッドは、Stringの新しいインスタンスも返します。

5

あなたは(奇妙なことと思われる)outパラメータを受け取り、戻り値としてそれを使用することですこれに得ることができる最も近い:

public static void ExtensionTest(this string input, out string output) 
{ 
    output = input + " Extended!"; 
} 

例:

string foo = "Hello World!"; 
foo.ExtensionTest(out foo); 

面白いがそれについてのことは、より密接に近いうちにと似ていますが、それは実際には少しタイプするだけです。

明確にするために:それはメソッド呼び出しのこの種を作るために、本当にあなたにとって重要でない限り、私は、これはお勧めしません。別の開発者が「WTF?」と発声する確率それを見ると100%のようなものになるはずです。

+0

+1非常に厄介です:) – leppie

+0

私はこれが好きです!投稿された質問に応じて適切な回避策です。良い仕事+1 – VoodooChild

1

拡張メソッド内の変数に新しい値を代入するには、パラメータのref修飾子が必要です。これは、C#コンパイラが拡張メソッドで許可していない(とにかく悪い考えです)。変数を変更していることを明確にする方が良いです。

0

可変文字列の場合は、より高速なStringBuilderを使用し、ref or out keywordを指摘してください。 StringBuilderは、基本的に文字列のリンクリストの改良です。
変更不可能な文字列は、C言語や他の多くの言語に近い動作を可能にする設計上の決定でした。

string str = "foo"; 

str += "bar"; // str will be free for garbage collection, 
//creating a new string object. 
//Note: not entirely true in later C# versions. 

StringBuilder sb = new StringBuild(); 
sb.Append("foo"); 
sb.Append("bar"); // appends object references to a linked list. 

も参照してください:あなたが呼び出しサイトの静的メソッドで `このref`修飾子を探しているよう