C#の隠された機能?[閉まっている]


1475

これは、この質問から次のことを学んだ後に思いつきました。

where T : struct

私たちC#開発者は、C#の基本を知っています。つまり、宣言、条件、ループ、演算子などです。

私たちの中には、ジェネリックス匿名型ラムダLINQなどをマスターする人もいます。

しかし、C#のファン、中毒者、専門家でさえほとんど知らないC#の最も隠された機能またはトリックは何ですか?

これまでに明らかになった機能は次のとおりです。


キーワード

の属性

構文

言語機能

Visual Studioの機能

  • ヒマドリによるエディターでテキストのブロックを選択
  • DannySmurfによるスニペット

フレームワーク

メソッドとプロパティ

ヒントとコツ

  • Andreas HR Nilssonによるイベントハンドラーの優れたメソッド
  • ジョンによる大文字の比較
  • dpによるリフレクションなしで匿名型にアクセスする
  • ウィルによってコレクションのプロパティを遅延してインスタンス化する簡単な方法
  • roosteronacidによる JavaScriptのような匿名インライン関数

その他の

回答:


752

これ自体はC#ではありませんが、実際に使用System.IO.Path.Combine()する必要がある範囲で実際に使用している人を見たことはありません。実際、Pathクラス全体は本当に便利ですが、誰も使用してません。

私はすべての本番アプリに次のコードが含まれていないはずですが、含まれていないことを望んでいます:

string path = dir + "\\" + fileName;

584

ラムダと型推論は過小評価されています。ラムダは複数のステートメント持つことができ、次のように自動的に互換性のあるデリゲートオブジェクトとして機能します(署名が一致することを確認してください)。

Console.CancelKeyPress +=
    (sender, e) => {
        Console.WriteLine("CTRL+C detected!\n");
        e.Cancel = true;
    };

とのnew CancellationEventHandlerタイプを指定する必要はありません。イベントから推測できます。これが、パラメータのタイプを指定することも必要とする全体を記述するのにそれほど面倒ではない理由です。senderedelegate (blah blah)

ラムダは何も返す必要がなく、型推論はこのようなコンテキストでは非常に強力です。

ところで、関数型プログラミングの意味でLambdaを作成するLambdaをいつでも返すことができます。たとえば、Button.Clickイベントを処理するラムダを作成するラムダは次のとおりです。

Func<int, int, EventHandler> makeHandler =
    (dx, dy) => (sender, e) => {
        var btn = (Button) sender;
        btn.Top += dy;
        btn.Left += dx;
    };

btnUp.Click += makeHandler(0, -1);
btnDown.Click += makeHandler(0, 1);
btnLeft.Click += makeHandler(-1, 0);
btnRight.Click += makeHandler(1, 0);

連鎖に注意してください。 (dx, dy) => (sender, e) =>

だから、関数型プログラミングクラスを受講できてうれしいです:-)

Cのポインター以外にも、これはあなたが学ぶべきもう1つの基本的なことだと思います:-)


528

リック・ストラールから:

連鎖できますか?演算子を使用して、一連のnull比較を実行できます。

string result = value1 ?? value2 ?? value3 ?? String.Empty;

454

エイリアスされたジェネリック:

using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

ASimpleName代わりにを使用できますDictionary<string, Dictionary<string, List<string>>>

多くの場所で同じ一般的な長くて複雑なものを使用する場合に使用します。


438

CLR C#を介しました

文字列を正規化する場合、Microsoftは大文字の比較を実行するためのコードを最適化しているため、ToLowerInvariantではなくToUpperInvariantを使用することを強くお勧めします。

同僚が比較する前に常に文字列を大文字に変更したことを覚えています。最初に小文字に変換する方が「自然」だと思うので、なぜ彼がそうするのかといつも思っていました。その本を読んだ後、私はその理由を知っています。


254
「文字列を大文字に変換」すると、2番目の一時的な文字列オブジェクトが作成されます。私はこの種の比較は好ましくない、最良の方法は次のとおりだと思いました:String.Equals(stringA、stringB、StringComparison.CurrentCultureIgnoreCase)whcihはこの使い捨て文字列をまったく作成しません。
アンソニー

32
小文字の文字列では実行できない大文字の文字列を比較する場合、どのような最適化を実行できますか?なぜ一方が他方より最適であるのか理解できません。
パラッパ

36
小文字ではなく大文字に変換することで、特定のカルチャでの不正な動作を防ぐこともできます。たとえば、トルコ語では、2つの小文字のiが同じ大文字のIにマップされます。詳細については、Googleの「トルコ語i」を使用してください。
Neil、

34
ToUpperInvariantとToLowerInvariantのベンチマークを試しました。.NET 2.0または3.5でのパフォーマンスに違いはありません。確かに、どちらか一方を「強く推奨」することを保証するものは何もありません。
Rasmus Faber、

19
ToUpperInvariantを使用すると、すべての文字が往復します。msdn.microsoft.com/en-us/library/bb386042.aspxを参照してください。比較のために、次のように書いてください"a".Equals("A", StringComparison.OrdinalIgnoreCase)
SLaks 2009年

408

私のお気に入りのトリックは、null合体演算子と括弧を使用して、コレクションを自動的にインスタンス化することです。

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }

23
読みにくいと思いませんか?
Riri、

72
そのnooのために読むのは少し難しい... er、経験の浅い。ただし、コンパクトで、プログラマが知って理解する必要のある2つのパターンと言語機能が含まれています。したがって、最初は難しいですが、学ぶ理由になるという利点があります。

38
遅延インスタンス化は、クラスの不変条件について考えないようにするのが貧弱な人間の選択であるため、いくらかの過ちです。また、並行性の問題もあります。
ジョンライデグレン2009

17
これは悪い習慣であり、プロパティを呼び出すことはそのようなことをするべきではないということを常に知らされてきました。そこに設定があり、値をnullに設定した場合、APIを使用している人にとっては非常に奇妙です。
Ian

8
@Joelは、ListOfFooをnullに設定することはクラスコントラクトの一部ではなく、適切な方法でもありません。そのため、セッターはありません。ListOfFooがコレクションを返し、nullを返さないことが保証されている理由もここにあります。2つの悪いこと(セッターを作成し、コレクションをnullに設定)を実行すると、期待が間違っているという非常に奇妙な不満です。ゲッターでEnvironment.Exit()を実行することもお勧めしません。しかし、それもこの回答とは関係ありません。

315

nullイベントハンドラーのチェックを回避する

宣言時に空のデリゲートをイベントに追加すると、呼び出す前に常にnullかどうかイベントをチェックする必要がなくなります。例:

public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!

あなたにこれをさせましょう

public void DoSomething()
{
    Click(this, "foo");
}

これの代わりに

public void DoSomething()
{
    // Unnecessary!
    MyClickHandler click = Click;
    if (click != null) // Unnecessary! 
    {
        click(this, "foo");
    }
}

この関連する議論とこのトピックに関するEric Lippertによるこのブログ投稿(および可能性のある欠点)も参照してください。


87
この手法に依存し、クラスをシリアル化する必要がある場合、問題が発生すると思います。イベントを削除し、逆シリアル化するとNullRefferenceを取得します。安全です。
sirrocco 2008年

16
イベントハンドラーをnullに設定できるため、null参照を取得でき、競合状態が発生します。
ロバートポールソン、

64
クイックプロファイルテストは、nullテストを使用しないダミーサブスクライブイベントハンドラーが、nullテストを使用するサブスクライブ解除イベントハンドラーの約2倍の時間を要することを示しています。nullテストのないマルチキャストイベントハンドラーは、nullテストのあるシングルキャストイベントハンドラーの約3.5倍の時間がかかります。
Pパパ

54
これにより、常にセルフサブスクライバーを持つだけで、nullチェックの必要がなくなります。空のイベントとしても、これは望ましくないオーバーヘッドを伴います。イベントを発生させたくないサブスクライバーがない場合は、常に空のダミーイベントを最初に発生させるとは限りません。私はこの悪いコードを考えます。
キース

56
上記のコメントの理由から、これはひどい提案です。コードを「クリーン」に見えるようにする必要がある場合は、拡張メソッドを使用してnullを確認し、イベントを呼び出します。変更権限のある人は間違いなくこの回答に短所を追加する必要があります。
グレッグ

305

その他すべて、プラス

1)暗黙のジェネリック(なぜメソッドだけでクラスではないのですか?)

void GenericMethod<T>( T input ) { ... }

//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23);      //Is enough.

2)1つのパラメーターを持つ単純なラムダ:

x => x.ToString() //simplify so many calls

3)匿名型と初期化子:

//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
    { "red", "#ff0000" },
    { "green", "#00ff00" },
    { "blue", "#0000ff" }
};

int[] arrayOfInt = { 1, 2, 3, 4, 5 };

別のもの:

4)自動プロパティは異なるスコープを持つことができます:

public int MyId { get; private set; }

私に思い出させるために@pzycomanをありがとう:

5)ネームスペースエイリアス(この特定の区別が必要になる可能性は高い):

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();

14
#3では、Enumerable.Range(1,5)を実行できます
Echostorm

18
int [] nums = {1,2,3};で配列を初期化できたと思います。1.0以降:)は「新しい」キーワードさえ必要としません
Lucas

13
パラメータなしのラムダ()=> DoSomething();
Pablo Retyk、2009年

5
私は両方を使用しました{get; 内部セット; }と{get; 保護されたセット。このパターンは一貫しています。
キース、

7
@Kirk Broadhurst-そうです- new web.Control()この例でも機能します。::あなたはというクラスを持つことができるので、文法力、それは、名前空間のエイリアスとしてプレフィックスを治療するwebweb::Controlしながら、構文は、仕事はまだだろうweb.Control構文は、クラスまたは名前空間を確認するかどうかを知ることはできません。そのため、::名前空間のエイリアスを作成するときは常に使用する傾向があります。
キース

286

「as」キーワードを長い間知りませんでした。

MyClass myObject = (MyClass) obj;

MyClass myObject = obj as MyClass;

2番目のメソッドは、objがMyClassではない場合、クラスキャスト例外をスローするのではなく、nullを返します。


42
それをやり過ぎないでください。(ToType)xのセマンティクスが必要な場合でも、構文が優先されるため、多くの人がを使用しているようです。
スコットランガム、

4
私はそれがより良いパフォーマンスを提供するとは思いません。あなたはそれをプロファイリングしましたか?キャストが失敗したときに(もちろんそれはありませんけれども...しかし、あなたは(MyClassの)キャストを使用するとき、彼らはすべてで起こるならば、それは違いはありませんので、失敗は、)(非常にまれな例外..ですと。
スコットランガム

7
これは、通常のケースでキャストが失敗した場合にのみ、より高いパフォーマンスを発揮します。それ以外の場合、直接キャスト(タイプ)オブジェクトの方が高速です。ただし、直接キャストでは、nullを返すよりも例外をスローする方が時間がかかります。
スペンス、

15
「as」キーワードと同じ行に沿って...「is」キーワードも同様に役立ちます。
dkpatt 2009年

28
あなたはそれを乱用して、後でInvalidCastExceptionが発生する可能性があったときにNullReferenceExceptionを発生させることができます。
AndreiRînea09年

262

私が気に入っている2つの点は自動プロパティなので、コードをさらに折りたたむことができます。

private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

なる

public string Name { get; set;}

また、オブジェクト初期化子:

Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();

なる

Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}

6
自動プロパティはC#3.0のみの機能であることに注意してください。
Jared Updike

21
自動プロパティは3.0コンパイラで導入されました。しかし、コンパイラーは2.0コードを出力するように設定できるため、問題なく機能します。古いコンパイラで自動プロパティを使用して2.0コードをコンパイルしないでください。
ジョシュアシャノン

74
多くの人が気づいていないのは、getとsetが異なるアクセシビリティを持つことができるということです。例:public string Name {get; プライベートセット;}
Nader Shirazie 2009年

7
自動プロパティの唯一の問題は、デフォルトの初期化値を提供することができないように見えることです。
スタインÅsmul09年

7
@ANeves:いいえ、そうではありません。そのページから:DefaultValueAttributeによって、メンバーが属性の値で自動的に初期化されることはありません。コードに初期値を設定する必要があります。 [DefaultValue]プロパティを太字(デフォルト以外を意味する)で表示するかどうかを判断するために、デザイナーに使用されます。
Roger Lipscombe 2010年

255

ジェネリック型の 'default'キーワード:

T t = default(T);

Tが参照型の場合は「null」になり、intの場合は0、ブールなどの場合はfalseになります。


4
プラス:タイプ?Nullable <type>のショートカットとして。default(int)== 0、ただしdefault(int?)== null。
10


221

@は、文字列内のエスケープ文字を無視するようコンパイラーに指示します。

これを明確にしたかっただけです...エスケープ文字を無視するようには指示していません。実際には、文字列をリテラルとして解釈するようコンパイラーに指示しています。

あなたが持っている場合

string s = @"cat
             dog
             fish"

実際には次のように出力されます(インデントに使用される空白も含まれることに注意してください):

cat
             dog
             fish

文字列には、インデントに使用したすべてのスペースが含まれていませんか?
アンディ、

18
はい、それは逐語的文字列と呼ばれます。
Joan Venge

4
出力に、出力されるスペースも表示されていれば、より明確になります。今のところ、改行文字は印刷されているように見えますが、スペースは無視されます。
aleemb

正規表現や長いSQLクエリのエスケープに非常に役立ちます。
ashes999 2010

また、マップする{{{して}}}する上で便利string.Format()
Ferruccio 2012年

220

C#(.NET 3.5)の最も評価されておらず、あまり知られていない機能の1つは、特に式ツリーですジェネリックスやラムダと組み合わせた場合のです。これは、NInjectやMoqなどの新しいライブラリが使用しているAPI作成へのアプローチです。

たとえば、APIでメソッドを登録し、そのAPIがメソッド名を取得する必要があるとします。

このクラスを考えると:

public class MyClass
{
     public void SomeMethod() { /* Do Something */ }
}

以前は、開発者がこれを文字列と型(または他の大部分は文字列ベース)で行うのを見るのは非常に一般的でした:

RegisterMethod(typeof(MyClass), "SomeMethod");

まあ、それは強いタイピングの欠如のために吸います。「SomeMethod」の名前を変更するとどうなりますか?しかし、3.5では、これを強く型付けされた方法で行うことができます。

RegisterMethod<MyClass>(cl => cl.SomeMethod());

RegisterMethodクラスは次のExpression<Action<T>>ように使用します。

void RegisterMethod<T>(Expression<Action<T>> action) where T : class
{
    var expression = (action.Body as MethodCallExpression);

    if (expression != null)
    {
        // TODO: Register method
        Console.WriteLine(expression.Method.Name);
    }
}

これが私がラムダスとエクスプレッションツリーに夢中になっている大きな理由の1つです。


3
私は...などのFieldInfo、PropertyInfo、と同じことを反射ユーティリティクラスを持っている
オルモ

はい、これは素晴らしいです。このようなメソッドを使用EditValue(someEmployee, e => e.FirstName);して、ビジネスロジックのようなコードを記述し、ViewModelとViewのすべての配管ロジックを自動的に生成して、そのプロパティを編集することができました(したがって、「First Name」というテキストのラベルとTextBoxユーザーが名前を編集するときにFirstNameプロパティのセッターを呼び出し、ゲッターを使用してビューを更新するバインディング。これは、C#の新しい内部DSLのほとんどの基礎となっているようです。
Scott Whitlock、

4
これらはあまり理解されていないほど、あまり知られていません。
Justin Morgan、

メソッドを登録する必要があるのはなぜですか?私はこれを以前に使用したことがありません-これはいつどこで使用されますか?
MoonKnight

209

利回り」が思い浮かぶ。[DefaultValue()]などの一部の属性も私のお気に入りです。

var」キーワードはもう少し知られていますが、.NET 2.0アプリケーションでも使用できること(.NET 3.5コンパイラ使用してそれを出力2.0コードに設定する限り)はあまり知られていないようです上手。

編集:kokos、指摘してくれてありがとう?演算子、それは本当に本当に便利です。(??は無視されるため)グーグルするのは少し難しいので、ここにその演算子のMSDNドキュメントページを示します。 ?? 演算子(C#リファレンス)


14
デフォルト値のドキュメントには、プロパティの値を実際に設定しているわけではないと記載されています。これはビジュアライザとコードジェネレータのヘルパーにすぎません。
Boris Callens

2
DefaultValueについて:当面の間、一部のライブラリはそれを使用しています。ASP.net MVCは、コントローラーアクションのパラメーターにDefaultValueを使用します(これはnullを許容しない型に非常に役立ちます)。もちろん厳密に言えば、値はコンパイラーではなくMVCのコードによって設定されるため、これはコードジェネレーターです。
Michael Stum

6
??の名前 オペレーターは "Null Coalescing"オペレーターです
Armstrongest

収量は私のお気に入りですが、合体演算子はそこにあります。CAS、またはアセンブリ署名、厳密な名前、GACについて何も表示されません... CASだけがC#だと思います...しかし、多くの開発者にはセキュリティについての手がかりがありません。
BrainSlugs83 2012

198

ほとんどのC#開発者は「null許容」型について知らないことがよくあります。基本的に、null値を持つことができるプリミティブ。

double? num1 = null; 
double num2 = num1 ?? -100;

NULL可能ダブル、設定しNUM1を定期的にダブル、設定した後、nullに、NUM2をする、NUM1または-100場合NUM1がヌルでした。

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

Nullable型についてもう1つ:

DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();

戻り値はString.Emptyです。詳細については、このリンクを確認してください


1
DateTimeをnullに設定することはできません。
Jason Jackson

2
それでは、 "int"はSystem.Int32のC#構文シュガーだけですか?Nullable型を中心に構築されたコンパイラサポートが実際にあり、たとえば、それらをnullに設定できるようにし(これは一般的な構造体だけでは実行できません)、それらを基になる型としてボックス化します。
Pダディ

4
@Pダディ-はい、intはSystem.Int32の構文糖です。intのように完全に交換可能ですか?=== Int32?=== Nullable <Int32> === Nullable <int>
cjk

6
@ck:はい、intはTとしてSystem.Int32のエイリアスですか?Nullable <T>のエイリアスですが、これは単なる構文上の砂糖ではありません。言語の定義された部分です。エイリアスは、コードを読みやすくするだけでなく、モデルによりよく適合します。Nullable <Double>をdoubleとして表現していますか?このように含まれる値は、Double型でインスタンス化されたいくつかの一般的な構造ではなく、doubleである(またはその可能性がある)との見方を強調しています。(続き)
Pダディ

3
いずれにせよ、議論はエイリアスに関するものではありませんでした(それは単なるアナロジーとしては不十分だと思います)、そのnull許容型は、任意の構文を使用して、実際にはジェネリックの製品ではなく言語機能です。nullのすべての機能(nullの比較/割り当て、演算子の転送、基になる型またはnullのボクシング、nullの結合とas演算子との互換性)をジェネリックだけで再現することはできません。Nullable <T>だけでは初歩的なものであり、優れたものではありませんが、言語の一部としてのnull許容型の概念はキックアスです。
Pダディ

193

ドキュメントに記載されていないC#キーワードの形式で、いくつかの興味深い非表示のC#機能を次に示します。

__makeref

__reftype

__refvalue

__arglist

これらはドキュメント化されていないC#キーワードであり(Visual Studioでも認識されます)、ジェネリックの前に効率的なボックス化/ボックス化解除のために追加されました。これらは、System.TypedReference構造体と連携して機能します。

可変長パラメーターリストに使用される__arglistもあります。

人々があまり知らない1つのことは、System.WeakReferenceです。これは、オブジェクトを追跡しながら、ガベージコレクターがオブジェクトを収集できる非常に便利なクラスです。

最も便利な「隠された」機能は、yield returnキーワードです。それは本当に隠されているわけではありませんが、多くの人々はそれについて知りません。LINQはこの上に構築されています。内部で状態マシンを生成することにより、クエリの遅延実行を可能にします。Raymond Chenは最近、内部のザラザラした詳細について投稿しました。


2
Peter Brombergによる文書化されていないキーワードの詳細。それを使用する理由があるかどうか私はまだ得ません。
HuBeZa、2011年

ジェネリックが登場した@HuBeZaでは、__ refType、__ makeref、__ refvalueを使用する正当な理由は多くありません(何か?)。これらは、前に.NET 2のジェネリックにボクシングを避けるために主に使用された
ユダガブリエルHimango

マット、.NET 2のジェネリックの導入により、これらのキーワードを使用する理由はほとんどありません。これらのキーワードの目的は、値の型を扱うときにボックス化を回避することだったからです。HuBeZaによるリンクを参照してください。また、codeproject.com / Articles / 38695 / UnCommon
Judah Gabriel Himango

185

純粋で安全なC#のユニオン(C ++共有メモリの種類)

安全でないモードとポインタに頼ることなく、クラス/構造体のメモリスペースをクラスメンバーに共有させることができます。次のクラスがあるとします。

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

Int32フィールドを操作することでバイトフィールドの値を変更でき、その逆も可能です。たとえば、このプログラム:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

これを出力します:

2147483647
FF FF FF 7F
65535

System.Runtime.InteropServicesを使用して追加するだけです。


7
@Georgeは、cユニオン宣言を使用してソケットを介してレガシーアプリと通信しているときに動作します。
scottm 2009

2
オフセット0でintおよびfloatと言うことにも意味があります。浮動小数点数をビットマスクとして操作する場合に必要ですが、これはときどき必要です。特に、浮動小数点数について新しいことを学びたい場合は。
ジョンライデグレン2009

2
これについての厄介なことは、これを使用する場合、コンパイラがinit関数のすべての変数を設定するように強制する構造体である場合です。したがって、次の場合:public A(int int32){Int32 = int32; 「フィールド 'One'は制御が呼び出し元に返される前に完全に割り当てられる必要があります」をスローするため、One = Two = Three = Four = 0;を設定する必要があります。同様に。
manixrock

2
これには用途があり、ほとんどがバイナリデータで使用されます。「Pixel」構造体をint32 @ 0で、4つのコンポーネント@ 0、1、2、3で4バイトを使用しています。画像データをすばやく簡単に操作するのに最適です。
snarf

57
警告:このアプローチはエンディアンを考慮していません。 つまり、C#コードはすべてのマシンで同じように実行されるわけではありません。リトルエンディアンCPU(最下位バイトを最初に格納する)では、示されている動作が使用されます。ただし、ビッグエンディアンのCPUでは、バイトは予想とは逆になります。これを製品コードで使用する方法に注意してください。コードは特定のモバイルデバイスや他のハードウェアに移植できず、明白でない方法で壊れる可能性があります(たとえば、2つのファイルは表面的には同じ形式ですが、実際にはバイト順が逆になっています)。
レイバーンズ

176

キーワードである変数名に@を使用します。

var @object = new object();
var @string = "";
var @if = IpsoFacto(); 

38
キーワードを変数名として使用する理由は何ですか?これにより、コードが読みにくくなり、難読化されるように思えます。
Jon

41
まあ、それがある理由は、C#キーワードをメンバー名として使用する可能性がある他の言語との相互運用性のためにCLIがそれを必要とするためです
Mark Cidade

69
asp.net MVC HTMLヘルパーを使用してHTMLクラスを定義したい場合は、@ classを使用してクラスのキーワードとして認識されないことを喜んで知っています
Boris Callens

31
拡張メソッドに最適です。public static void DoSomething(this Bar @this、string foo){...}
Jonathan C Dickinson

45
@zihotki:不正解です。変数a = 5; Console.WriteLine(@a); Prints 5
SLaks

168

finallyブロックまたはファイナライザを呼び出さずにプログラムを終了する場合は、FailFastを使用します。

Environment.FailFast()

12
このメソッドは、メモリダンプも作成し、Windowsエラーログにメッセージを書き込むことに注意してください。
RickNZ、2009

1
このメソッドが使用される場合、ファイナライザやアプリドメインのアンロードイベントは呼び出されないことに注意してください...
AwkwardCoder

1
ヒントは+1ですが、これはC#ではなく、.NETのBCLです。
Abel

System.Diagnostics.Process.GetCurrentProcess()。Kill()の方が高速です
Tolgahan Albayrak '30 / 10/30

153

メソッドから匿名型を返し、リフレクションなしでメンバーにアクセスします。

// Useful? probably not.
private void foo()
{
    var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
    Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}

object GetUserTuple()
{
    return new { Name = "dp", Badges = 5 };
}    

// Using the magic of Type Inference...
static T AnonCast<T>(object obj, T t)
{
   return (T) obj;
}

42
それは本当にあなたに何もしません。それは実際には危険です。GetUserTupleが複数の型を返すように変更された場合はどうなりますか?キャストは実行時に失敗します。C#/。Netの優れた点の1つは、コンパイル時のチェックです。新しいタイプを作成する方がはるかに良いでしょう。
Jason Jackson

9
@ジェイソン私はそれはおそらく役に立たないと言ったが、それは驚くべきことだ(そして私は隠されていると思った)。
denis phillips

31
かっこいいですが、これはデザインの選択としてはかなり貧弱なようです。基本的に、匿名型を2か所で定義しました。その時点で、実際の構造体を宣言して直接使用するだけです。
ポールアレクサンダー

6
@ジョージ:そのような慣習は...構造体と呼ばれるでしょうか?
R.マルティーニョフェルナンデス

2
このトリックは「サンプルごとのキャスト」という名前で、匿名型を返すメソッドが別のアセンブリにある場合は機能しません。
desco

146

正規表現とファイルパスに役立つものを次に示します。

"c:\\program files\\oldway"
@"c:\program file\newway"

@は、文字列内のエスケープ文字を無視するようコンパイラーに指示します。


27
また、@定数は内部で改行を受け入れます。文字列に複数行のスクリプトを割り当てるときに最適です。
Tor Haugen

11
つまり、引用符を2倍にするだけでエスケープすることも忘れないでください。[code] var candy = @ "I like" "red" "candy canes。"; [/ code]
Dave

5
Path.Combineでパスを作成する傾向があります。私は間違いなく@を正規表現に使用します!
Dan McClain、

6
@newもキーワードではなく変数です。@ this、@ int、@ return、@ interface ... so on :)
IAbstract

これは近くにはありません: しかし、C#のファン、中毒者、専門家でさえほとんど知らないC#の最も隠された機能またはトリックは何ですか?
publicgk 2011

141

ミックスイン。基本的に、機能を複数のクラスに追加したいが、それらすべてに1つの基本クラスを使用できない場合は、各クラスにインターフェイスを実装するようにします(メンバーなし)。次に、インターフェイスの拡張メソッド記述します

public static DeepCopy(this IPrototype p) { ... }

もちろん、いくつかの明快さは犠牲になります。しかし、うまくいきます!


4
ええ、これが拡張メソッドの本当の力だと思います。それらは基本的にインターフェースメソッドの実装を可能にします。
ジョンブブリスキー

これは、NHibernate(またはCastle ActiveRecord)を使用していて、コレクションのインターフェイスを使用する必要がある場合にも便利です。このようにして、コレクションインターフェイスに動作を与えることができます。
Ryan Lundy

記録のために、これが基本的にすべてのLINQメソッドの実装方法です。
WCWedin

NHibernateまたはCastle ActiveRecordのコレクションインターフェースで拡張メソッドを使用して、上記で言及した内容を説明するリンクは次のとおりです。devlicio.us
Ryan Lundy

7
拡張プロパティが許可されている場合のみ!!!! 私は、読み取り専用プロパティであるように懇願した拡張メソッドを記述する必要がありませんでした...
John Gibb

130

なぜ誰もがNullable <bool>を使いたがる理由がわかりません。:-)

True、False、FileNotFound


87
ユーザーが「はい」か「いいえ」の質問に答えることを期待している場合、質問が答えられていない場合はnullが適切です
Omar Kooheji '24年

22
null可能型は、テーブルの列がnull可能であることが多いデータベースとのやり取りに便利です。
tuinstoel

11
はい、いいえ、メイビー?
ダン・ブレア

21
ThreeStateのCheckBoxのストア値
シミーWeitzhandler

8
SQLの場合:はい/いいえ/不明。
erikkallen 2009

116

これは、誤った名前が付けられているため、「隠されている」わけではありません。

「マップ」、「リデュース」、「フィルター」のアルゴリズムに多くの注意が払われています。.NET 3.5はこれらの3つのアルゴリズムをすべて追加しましたが、それらがLINQの一部であるという事実に基づいて、非常にSQLっぽい名前を付けたことは、ほとんどの人が気付かないことです。

"map" => Select
データをあるフォームから別のフォームに変換します

"reduce" =>
Aggregate値を単一の結果に集約します

"filter" => Where
基準に基づいてデータをフィルタリングします

LINQを使用して、反復と条件式を使用していたコレクションでインライン作業を行う機能は、非常に貴重な場合があります。すべてのLINQ拡張メソッドがどのようにしてコードをよりコンパクトで保守可能にするのに役立つかを学ぶことは価値があります。


1
Selectはモナドの "return"関数のようにも機能します。stackoverflow.com/questions/9033/hidden-features-of-c#405088を
Mark Cidade

1
「select」の使用は、SQLish構文を使用する場合にのみ必要です。拡張メソッド構文-someCollection.Where(item => item.Price> 5.99M)を使用する場合、selectステートメントを使用する必要はありません。
Brad Wilson

7
@Brad、それ(場所)はフィルター操作です。選択せずにマップ操作を試してください...
Eloff

2
LINQは、私の意見でのC#に起こった大きなものである:stackoverflow.com/questions/2398818/...
Leniel Maccaferri

1
Aggregateの最小のシグネチャは「reduce」関数で、Aggregateの真ん中のシグネチャははるかに強力な「fold」関数です!
Brett Widmeier、2011年

115
Environment.NewLine

システムに依存しない改行。


10
これについての厄介なことは、コンパクトフレームワークに含まれていないことです。
Stormenet 2008

14
これはアプリケーションのホストプラットフォームに固有であることを指摘する価値があります。別のシステム向けのデータを作成する場合は、\ nまたは\ r \ nを適切に使用する必要があります。
メッシュ

これは.NETのBCLの一部であり、C#自体の機能ではありません。
アベル

111

String.Format式内で中括弧を使用しようとしている場合...

int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"

19
@キラレッサ:実際、そうです、それらは中括弧ですが、「中括弧」はそれらの別名です。[および]は角括弧であり<、および>は山括弧です。en.wikipedia.org/wiki/Bracketを参照してください。
icktoofay 2010年

4
あなたは正しいです。しかし、私がコメントしたとき、それは「中」括弧を言っていませんでした。
Ryan Lundy

2
指摘するのはとてもいいことです。最初のString.Formatが次のようになっていることを思い出してください。これらのエスケープが{{および}}を使用して行われることがわかったら、私はとても幸せでした:)
Gertjan

Muahahahaa ... .Netでのプログラミングはすでに3年で、私はこれを知りませんでした。:D
Arnis Lapsa 2010

エスケープシーケンスと同様に機能する「中かっこ」の括弧??
Pratik

104
  1. ?? -合体演算子
  2. using(statement / directive)-Disposeを呼び出すだけでなく、他にも使用できる素晴らしいキーワード
  3. 読み取り専用 -さらに使用する必要があり ます
  4. netmodules-残念ですが、Visual Studioにはサポートがありません

6
usingを使用して、長い名前空間をより便利な文字列にエイリアスすることもできます。つまり、次のように使用します。詳細はこちら: msdn.microsoft.com/en-us/library/sf0df423.aspx
Dave R.

2
それは本当に同じことではありません。Disposeを呼び出す場合は、usingステートメントを使用できます。型のエイリアスを作成する場合は、usingディレクティブを使用します。
ØyvindSkaar

2
(3項演算子で行ったように)#1の名前が必要な場合に備えて、?? ヌル合体演算子と呼ばれます。
J.スティーン

4
@LucasAardvark:J Steenが言及したように、これはヌル合体演算子と呼ばれます。検索してください!
ココス2009年

1
??を検索するには googleでの演算子try:google.com/search
backslash17

103

@エド、私はこれを投稿することについて少し控えめに言っています。しかし、私はあなたのコードサンプルでそれを指摘します:

MyClass c;
  if (obj is MyClass)
    c = obj as MyClass

「is」を使用する場合、なぜ「as」を使用して安全なキャストでフォローアップするのですか?objが確かにMyClassであることが確認できたら、沼地の標準キャスト:

c = (MyClass)obj

...失敗することはありません。

同様に、あなたはただ言うことができます:

MyClass c = obj as MyClass;
if(c != null)
{
   ...
}

確かに.NETの内部について十分な知識はありませんが、本能は、これにより最大2つの型キャスト操作を最大1つに削減できると教えています。いずれにせよ処理銀行を破る可能性はほとんどありません。個人的には後者も綺麗に見えると思います。


16
キャストが正確なタイプ(オブジェクトが "A"の場合は "A"にキャストされ、それから派生していない)の場合、ストレートキャストは "as"より〜3x高速です。派生型をキャストするとき(オブジェクトが "B"のときに "A"から派生し、 "A"から派生する)、ストレートキャストは "as"より〜0.1倍遅くなります。「ある」、「ある」はばかげている。
Pダディ

2
いいえ、ただし「if((c = obj as MyClass)!= null)」と書くこともできます。
Dave Van den Eynde 2009年

10
isそしてas、ユーザキャストを行うことはありません。したがって、上記のコードはis、objがMyClassから派生しているかどうか(または暗黙のシステム定義キャストがあるかどうか)をオペレーターに尋ねています。また、でis失敗しnullます。これらのエッジケースはどちらも、コードにとって重要な場合があります。たとえば、次のように記述したい場合があります。if( obj == null || obj is MyClass ) c = (MyClass)obj; ただし、これは厳密には異なりtry { c = (MyClass)obj; } catch { }ます。前者はユーザー定義の変換を実行しませんが、後者は実行します。なければnull、チェック、前者はまた、設定されていないだろうcときobjですnull
Adam Luter、

2
ILでは、キャストはCASTCLASSに行きますが、as / isはISINST命令に行きます。
ジョン・ギブ

5
私はこのテストを実行し、にキャストIEnumerable<int>List<int>objectnew object())をIEnumerable<int>にキャストして、間違いがないことを確認しました:直接キャスト:5.43ns、is-> asキャスト:6.75ns、asキャスト:5.69ns。次に、無効なキャストのテスト:ダイレクトキャスト:3125000ns、キャストとして:5.41ns。結論:1%の要素について心配するのをやめて、キャストが無効である可能性がある場合は必ず使用するようにしてください。例外(処理されている場合も)がキャストに比べて非常に遅いので、係数578000の方が遅いと言います。最後の部分は覚えておいてください。残りは重要ではありません(.Net FW 4.0、リリースビルド)
Aidiakapi '13

98

たぶん高度なテクニックではないかもしれませんが、私がいつも気が狂うテクニックは次のとおりです。

if (x == 1)
{
   x = 2;
}
else
{
   x = 3;
}

以下に圧縮できます。

x = (x==1) ? 2 : 3;

10
三項演算子は私のグループで禁止されています。理由がわからない人もいますが、気に入らない人もいます。
ジャスティンR.

13
それらは同じではなく、ステートメントではなく演算子であるためだと思います。私は最初のアプローチを自分で好みます。より一貫性があり、簡単に拡張できます。演算子にはステートメントを含めることができないため、本文を拡張する必要がある場合は、その3項演算子をifステートメントに変換する必要があります
kervin

16
x ++に圧縮できます。[OK]を、それは無意味だ^^
フランソワ・

5
@ギラウム:xのすべての値を考慮する:x = 2 + System.Math.Min(1、System.Math.Abs​​(x-1));
mbeckish

38
これは実際には「条件演算子」と呼ばれます-3つの引数を取るため 3項演算子です。en.wikipedia.org/wiki/Conditional_operator
Blorgbeardは、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.