1473

この質問から次のことを学んだ後、これが頭に浮かびました。

where T : struct

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

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

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

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


キーワード

属性

構文

  • ??(coalesce nulls)kokosによる演算子
  • NickBerardiによる番号フラグ
  • where T:newLarsMæhlum
  • キースによる暗黙のジェネリック
  • キースによる1パラメーターラムダ
  • キースによる自動車の特性
  • キースによる名前空間エイリアス
  • Patrickによる@付きの逐語的な文字列リテラル
  • enumlfoustによる値
  • @variablenames by marxidad
  • eventmarxidadによるオペレーター
  • Portmanによる文字列ブラケットのフォーマット
  • xanadontによるプロパティアクセサーアクセシビリティ修飾子
  • JasonS?:による条件付き(三項)演算子( )
  • checkedBinojAntonyuncheckedによるオペレーター
  • implicit and explicitFloryによるオペレーター

言語機能

VisualStudioの機能

  • Himadriによるエディターでテキストのブロックを選択します
  • DannySmurfによるスニペット

フレームワーク

メソッドとプロパティ

ヒントとコツ

  • AndreasHRNilssonによるイベントハンドラーの優れた方法
  • ジョンによる大文字の比較
  • dpによる反映なしで匿名タイプにアクセスする
  • Willによってコレクションプロパティを遅延インスタンス化する簡単な方法
  • JavaScriptのような匿名インライン-roosteronacidによる関数

他の

4

296 に答える 296

751

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

すべての本番アプリには次のコードがあると確信していますが、そうすべきではありません。

string path = dir + "\\" + fileName;
于 2008-08-13T01:53:50.460 に答える
583

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

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

私は a を持っておらず、 andnew CancellationEventHandlerの型を指定する必要もないことに注意してください。それらはイベントから推測できます。これが、パラメーターのタイプを指定する必要がある全体を記述するのが面倒ではない理由です。senderedelegate (blah blah)

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

ところで、関数型プログラミングの意味でラムダを作るラムダをいつでも返すことができます。たとえば、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 つの基本的なことだと思います :-)

于 2008-08-26T18:34:44.433 に答える
527

Rick Strahlより:

?? をチェーンできます。演算子を使用して、一連の null 比較を実行できるようにします。

string result = value1 ?? value2 ?? value3 ?? String.Empty;
于 2008-08-19T05:43:53.457 に答える
453

エイリアスジェネリック:

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

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

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

于 2008-09-16T16:53:37.230 に答える
437

CLRからC#経由

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

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

于 2008-08-15T11:06:48.747 に答える
407

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

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }
于 2008-09-12T13:25:55.610 に答える
314

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 によるこのブログ投稿(および考えられる欠点)も参照してください。

于 2008-08-12T21:57:39.267 に答える
304

他のすべてに加えて

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();
于 2008-08-12T18:23:40.587 に答える
285

「as」キーワードをしばらく知りませんでした。

MyClass myObject = (MyClass) obj;

MyClass myObject = obj as MyClass;

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

于 2008-08-12T16:42:04.113 に答える
261

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

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()}
于 2008-08-13T07:39:13.493 に答える
254

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

T t = default(T);

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

于 2008-08-13T10:20:07.147 に答える
225

一般的な属性ですが、最も重要なのはDebuggerDisplayです。何年も節約できます。

于 2008-08-12T16:59:40.460 に答える
220

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

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

あなたが持っている場合

string s = @"cat
             dog
             fish"

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

cat
             dog
             fish
于 2008-08-13T02:07:26.267 に答える
219

C# (.NET 3.5) の最も過小評価され、あまり知られていない機能の 1 つは、特にGenerics および Lambdas と組み合わせた場合のExpression Treesだと思います。これは、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 つです。

于 2008-09-09T21:52:00.237 に答える
208

利回り」が頭に浮かぶでしょう。[DefaultValue()]のような属性のいくつかも私のお気に入りの1つです。

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

編集:kokos、指摘してくれてありがとう?? 演算子、それは確かに本当に便利です。グーグルで検索するのは少し難しいので(??は無視されるだけなので)、そのオペレーターのMSDNドキュメントページは次のとおりです。演算子(C#リファレンス)

于 2008-08-12T16:34:44.970 に答える
197

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

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

null 許容 double num1を null に設定してから、通常の double num2num1に設定するか、 num1が null の場合は-100に設定します。

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

Nullable 型に関するもう 1 つのこと:

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

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

于 2008-08-12T17:07:59.350 に答える
192

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

__makeref

__reftype

__refvalue

__arglist

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

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

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

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

于 2008-08-12T18:50:29.720 に答える
184

純粋で安全な 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; を使用して追加するだけです。

于 2008-09-23T20:39:01.003 に答える
175

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

var @object = new object();
var @string = "";
var @if = IpsoFacto(); 
于 2008-08-18T01:45:02.193 に答える
167

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

Environment.FailFast()
于 2008-10-13T22:25:51.980 に答える
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;
}
于 2008-08-17T01:01:28.397 に答える
146

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

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

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

于 2008-08-12T18:38:16.157 に答える
141

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

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

もちろん、ある程度の明瞭さは犠牲になります。しかし、それはうまくいきます!

于 2008-10-26T19:04:33.183 に答える
130

ただし、 Nullable<bool> を使用したい理由はわかりません。:-)

True、False、FileNotFound ?

于 2008-08-12T18:53:44.333 に答える
116

これは、名前が間違っているほど「隠されている」わけではありません。

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

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

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

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

LINQ を使用して、反復と条件分岐を使用していたコレクションでインライン処理を実行できることは、非常に価値があります。すべての LINQ 拡張メソッドが、コードをよりコンパクトで保守しやすくするのにどのように役立つかを学ぶことは価値があります。

于 2008-08-16T23:55:28.373 に答える
115
Environment.NewLine

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

于 2008-09-01T00:03:41.560 に答える
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"
于 2008-08-18T22:29:45.020 に答える
104
  1. ?? -合体演算子
  2. using(ステートメント/ディレクティブ)-Disposeの呼び出し以外にも使用できる優れたキーワード
  3. 読み取り専用-もっと使用する必要があります
  4. netmodules-残念ながら、VisualStudioではサポートされていません
于 2008-08-12T16:35:55.703 に答える
103

@Ed、私はこれを投稿することに少し気が進まない。ただし、コードサンプルで次のことを指摘します。

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 つに削減されることがわかります。どちらの方法でも、処理バンクを壊す可能性はほとんどありません。個人的には、後者の方がきれいに見えると思います。

于 2008-08-12T18:03:12.203 に答える
98

高度なテクニックではないかもしれませんが、私が常々目にするものは、私を夢中にさせます:

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

次のように要約できます。

x = (x==1) ? 2 : 3;
于 2008-08-19T15:54:52.677 に答える
94

多くの人は、someString.ToUpper() を実行する代わりに OrdinalIgnoreCase を使用して文字列を比較できることに気づいていません。これにより、追加の文字列割り当てのオーバーヘッドがなくなります。

if( myString.ToUpper() == theirString.ToUpper() ){ ... }

になる

if( myString.Equals( theirString, StringComparison.OrdinalIgnoreCase ) ){ ... }
于 2009-04-15T00:23:53.073 に答える
79

学習したばかりの匿名型は、変数名からプロパティ名を推測できます。

string hello = "world";
var o = new { hello };
Console.WriteLine(o.hello);
于 2008-10-17T16:41:51.873 に答える
75

私は次のようなリストで検索するのが好きです:-

bool basketContainsFruit(string fruit) {
  return new[] { "apple", "orange", "banana", "pear" }.Contains(fruit);
}

それよりも:-

bool basketContainsFruit(string fruit) {
  return fruit == "apple" || fruit == "orange" || fruit == "banana" ||
    fruit == "pear";
}

実際にはそれほど多くは出てきませんが、アイテムを検索の主題と照合するというアイデアは、非常に便利で簡潔なものになる可能性があります。

于 2008-08-28T20:59:59.060 に答える
75

正直なところ、まさにその定義による専門家はこのことを知っているべきです。しかし、あなたの質問に答えるために:組み込み型テーブル(C#リファレンス)

数値のフラグを立てるコンパイラは、次の点で広く知られています。

Decimal = M
Float = F
Double = D

// for example
double d = 30D;

ただし、これらはよりあいまいです。

Long = L
Unsigned Long = UL
Unsigned Int = U
于 2008-08-12T16:38:50.703 に答える
73

InternalsVisibleTo属性はあまり知られていませんが、特定の状況では非常に便利です。基本的に、別のアセンブリが定義アセンブリの「内部」要素にアクセスできるようにします。

于 2008-09-05T16:10:21.047 に答える
72

C# 4.0 の文字列クラスの新しいメソッドを次に示します。

String.IsNullOrWhiteSpace(String value)

そろそろ時間だ。

于 2010-06-22T03:59:04.763 に答える
70

ReSharperを使用しているときにこれを拾いました:

暗黙的なメソッドグループの変換

//If given this:
var myStrings = new List<string>(){"abc","def","xyz"};
//Then this:
myStrings.ForEach(s => Console.WriteLine(s));
//Is equivalent to this:
myStrings.ForEach(Console.WriteLine);

詳細については、「C#での暗黙的なメソッドグループの変換」を参照してください。

于 2008-10-06T15:30:27.870 に答える
68

デバッグ時$exceptionに、Watch \ QuickWatch \ Immediateウィンドウに入力して、現在のフレームを除くすべての情報を取得できます。これは、1回目の例外がオンになっている場合に非常に便利です。

于 2010-06-22T19:22:03.763 に答える
68

他にもありますが、それは私の頭のてっぺんにある 3 つの明白なものです...

于 2008-08-12T16:45:22.813 に答える
66

Dictionary.TryGetValue(K キー、V 値を出力)

チェックとゲットインとして機能します。それよりも;

if(dictionary.ContainsKey(key)) 
{
    value = dictionary[key];
    ...
}

あなたはただすることができます。

if(dictionary.TryGetValue(key, out value)) 
{ ... }

と値が設定されました。

于 2008-09-19T20:02:05.340 に答える
65

条件付き string.Format :

数値が正、負、ゼロのいずれであるかに応じて、数値に異なる書式を適用します。

string s = string.Format("{0:positive;negative;zero}", i);

例えば

string format = "000;-#;(0)";

string pos = 1.ToString(format);     // 001
string neg = (-1).ToString(format);  // -1
string zer = 0.ToString(format);     // (0)
于 2009-08-05T05:57:55.170 に答える
64

イベントは実際には内部でデリゲートであり、デリゲートオブジェクトには複数の関数をアタッチし、それぞれ+=および-=演算子を使用してデタッチすることができます。

イベントは、+ =および-=が使用されている場合に呼び出されることを除いて、get / setと同様に、add/removeを使用して制御することもできます。

public event EventHandler SelectiveEvent(object sender, EventArgs args) 
  { add 
     { if (value.Target == null) throw new Exception("No static handlers!");
       _SelectiveEvent += value;
     }
    remove
     { _SelectiveEvent -= value;
     }
  } EventHandler _SelectiveEvent;
于 2008-08-18T07:33:17.560 に答える
61

gotoを忘れないでください。

于 2008-09-18T02:33:51.023 に答える
56

ランタイム機能のようなものですが、ガベージ コレクターが 2 つあることを最近知りました。ワークステーション gc とサーバー gc。Windows のクライアント バージョンではワークステーションがデフォルトですが、マルチコア マシンではサーバーの方がはるかに高速です。


<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

気をつけて。サーバー gc にはより多くのメモリが必要です。

于 2008-10-18T11:54:28.583 に答える
55

私はこれを上から見ることができませんでした-最近まであなたができることに気づかなかったのは、あるコンストラクターを別のコンストラクターから呼び出すことです:

class Example
{
    public Example(int value1)
        : this(value1, "Default Value")
    {
    }

    public Example(int value1, string value2)
    {
        m_Value1 = value1;
        m_value2 = value2;
    }

    int m_Value1;
    string m_value2;
}
于 2008-09-15T14:58:26.657 に答える
55

「投げる」を使う 「throw ex;」の代わりに スタックトレースを保持する

追加情報を追加せずに例外を再スローする場合は、「throw ex」の代わりに「throw」を使用します。catch ブロック内の空の "throw" ステートメントは、元のスタック トレースを保持しながら例外を再スローする特定の IL を発行します。「throw ex」は、例外の元のソースへのスタック トレースを失います。

于 2009-06-16T17:14:06.730 に答える
55

その他の十分に使用されていない演算子はcheckedanduncheckedです。

short x = 32767;   // 32767 is the max value for short
short y = 32767;
int z1 =  checked((short)(x + y));   //will throw an OverflowException
int z2 =  unchecked((short)(x + y)); // will return -2
int z3 =  (short)(x + y);            // will return -2
于 2008-12-10T13:11:49.433 に答える
48

私が遭遇したいくつかの隠された機能:

  • stackallocこれにより、スタックに配列を割り当てることができます
  • 非 out/ref パラメーターを持つ任意のデリゲート型に暗黙的に変換できる、明示的なパラメーター リストのない匿名メソッド (以前のコメントで述べたように、イベントには非常に便利です)
  • 多くの人は、イベントが実際に何であるかを認識していません (プロパティの get/set のようなメソッドの追加/削除のペア)。C# のフィールドのようなイベントは、実際には変数イベントの両方を宣言します。
  • ==and演算子をオーバーロードして、!=以外の型を返すことができますbool。奇妙ですが本当です。
  • C# 3 でのクエリ式の変換は、いくつかの点で非常に「単純」です。これは、非常に奇妙なことを実行できることを意味します。
  • Null 許容型には特別なボックス化動作があります。null 値は null 参照にボックス化され、null から null 許容型にもボックス化を解除できます。
于 2008-09-26T15:28:11.950 に答える
48

コメントなしでそのコードをコピーしたかっただけです。したがって、秘訣は単に Alt ボタンを押してから、好きな長方形を強調表示することです (例: 下)。

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        //if (e.CommandName == "sel")
        //{
        //    lblCat.Text = e.CommandArgument.ToString();
        //}
    }

上記のコードで、選択したい場合:

e.CommandName == "sel"

lblCat.Text = e.Comman

次に、Alt キーを押して四角形を選択します。行のコメントを外す必要はありません。

これをチェックしてください。

于 2009-11-09T06:58:35.877 に答える
46

フィールドが複数のスレッドによって同時に変更される可能性があることをコンパイラーに伝えるためのvolatileキーワード。

于 2008-09-12T18:24:24.410 に答える
46

@ダコタのデビッド:

Console.WriteLine( "-".PadRight( 21, '-' ) );

String クラスに同じことをよりクリーンな方法で実行できるコンストラクターがあることを発見するまで、私はこれを行っていました。

new String('-',22);
于 2008-09-05T13:54:30.030 に答える
45

params キーワード、つまり

public void DoSomething(params string[] theStrings)
{
  foreach(string s in theStrings)
  {
    // Something with the Strings…
  }
}

のように呼ばれる

DoSomething(“The”, “cat”, “sat”, “on”, “the” ,”mat”);
于 2008-10-03T05:34:22.927 に答える
45

私が好きなもののいくつか:

-似たようなインターフェースを作成する場合

 public interface SomeObject<T> where T : SomeObject<T>, new()

このインターフェイスから継承するものはすべて、パラメーターなしのコンストラクターを含むように強制します。これは、私が遭遇したいくつかのことに非常に役立ちます。

-匿名型を使用して、便利なオブジェクトをその場で作成する:

var myAwesomeObject = new {Name="Foo", Size=10};

-最後に、多くの Java 開発者は次のような構文に精通しています。

public synchronized void MySynchronizedMethod(){}

ただし、C# では、これは有効な構文ではありません。回避策はメソッド属性です:

 [MethodImpl(MethodImplOptions.Synchronized)]
 public void MySynchronizedMethod(){}
于 2008-09-09T14:04:46.413 に答える
44

Foreach は Duck Typing を使用します

これについては、 Krzysztof Cwalinas のブログからの言い換え、または恥知らずな盗用です。何よりも面白いトリビア。

オブジェクトが foreach をサポートするために、IEnumerableを実装する必要はありません。つまり、これは制約ではなく、コンパイラによってチェックされません。チェックしているのは、

  • オブジェクトは、パブリック メソッドGetEnumeratorを 提供します。
    • パラメータを取らない
    • 2 つのメンバーを持つ型を返す
      1. ブール値を返すパラメーターなしのメソッド MoveNext
      2. オブジェクトを返すゲッターを持つCurrent プロパティ

例えば、

class Foo
{
    public Bar GetEnumerator() { return new Bar(); }

    public struct Bar
    {
        public bool MoveNext()
        {
            return false;
        }

        public object Current
        {
            get { return null; }
        }
    }
}

// the following complies just fine:
Foo f = new Foo();
foreach (object o in f)
{
    Console.WriteLine("Krzysztof Cwalina's da man!");
}
于 2008-09-04T21:06:29.627 に答える
42

静的コンストラクター。

インスタンス:

public class Example
{
    static Example()
    {
        // Code to execute during type initialization
    }

    public Example()
    {
        // Code to execute during object initialization
    }
}

静的クラス:

public static class Example
{
    static Example()
    {
        // Code to execute during type initialization
    }
}

MSDNは次のように述べています

静的コンストラクターは、静的データを初期化するため、または一度だけ実行する必要がある特定のアクションを実行するために使用されます。最初のインスタンスが作成される前、または静的メンバーが参照される前に、自動的に呼び出されます。

例えば:

public class MyWebService
{
    public static DateTime StartTime;

    static MyWebService()
    {
        MyWebService.StartTime = DateTime.Now;
    }

    public TimeSpan Uptime
    {
        get { return DateTime.Now - MyWebService.StartTime; }
    }
}

ただし、次のように簡単に行うこともできます。

public class MyWebService
{
    public static DateTime StartTime = DateTime.Now;

    public TimeSpan Uptime
    {
        get { return DateTime.Now - MyWebService.StartTime; }
    }
}

そのため、実際に静的コンストラクターを使用する必要がある場合、インスタンスを見つけるのに苦労するでしょう。

MSDN は、静的コンストラクターに関する有用なメモを提供しています。

  • 静的コンストラクターは、アクセス修飾子やパラメーターを取りません。


  • 最初のインスタンスが作成される前、または静的メンバーが参照される前に、クラスを初期化するために静的コンストラクターが自動的に呼び出されます。

  • 静的コンストラクターを直接呼び出すことはできません。

  • ユーザーは、静的コンストラクターがプログラムで実行されるタイミングを制御できません。

  • 静的コンストラクターの一般的な使用法は、クラスがログ ファイルを使用しており、コンストラクターを使用し
    てこのファイルにエントリを書き込む場合です。

  • 静的コンストラクターは、コンストラクターが LoadLibrary メソッドを呼び出すことができる
    場合、アンマネージ コードのラッパー クラスを作成するときにも役立ちます。

  • 静的コンストラクターが例外をスローした場合、ランタイムは
    それを 2 回目に呼び出すことはなく
    、プログラムが実行されているアプリケーション ドメインの有効期間中、型は初期化されないままになります。

最も重要な注意点は、静的コンストラクターでエラーが発生した場合、 aTypeIntializationExceptionがスローされ、問題のあるコード行にドリルダウンできないことです。TypeInitializationException代わりに、特定の原因であるのInnerExceptionメンバーを調べる必要があります。

于 2008-09-19T07:48:12.320 に答える
40

System.Diagnostics名前空間の他のいくつかの属性は非常に役立ちます。

DebuggerBrowsableを使用すると、デバッガー ウィンドウから変数を非表示にできます (公開されたプロパティのすべてのプライベート バッキング変数に使用されます)。それに加えて、DebuggerStepThroughは、デバッガーがそのコードをステップ実行するようにします。これは、ダム プロパティに非常に役立ちます (C# 3.0 コンパイラに依存できる場合は、おそらく自動プロパティに変換する必要があります)。例として

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string nickName;
public string NickName    {
    [DebuggerStepThrough]
    get { return nickName; }
    [DebuggerStepThrough]
    set { this.nickName = value; }
}
于 2008-08-28T21:46:35.407 に答える
39

C#+ CLR:

  1. Thread.MemoryBarrier:ほとんどの人はそれを使用しなかったでしょうし、MSDNには不正確な情報がいくつかあります。しかし、複雑さを知っているなら、気の利いたロックフリー同期を行うことができます。

  2. volatile, Thread.VolatileRead, Thread.VolatileWrite:これらを利用する人は非常に少なく、回避して導入するすべてのリスクを理解している人はさらに少なくなります:)。

  3. ThreadStatic変数:過去数年間に1つの状況しかありませんでしたが、ThreadStatic変数は絶対に神からの送信であり、不可欠であることがわかりました。たとえば、コールチェーン全体に対して何かをしたい場合、それらは非常に便利です。

  4. fixedキーワード:C ++とほぼ同じ速度で大きな配列の要素にアクセスしたい場合、これは隠された武器です(デフォルトでは、C#は境界チェックを実施して速度を低下させます)。

  5. default(typeName)キーワードはジェネリッククラスの外でも使用できます。構造体の空のコピーを作成すると便利です。

  6. 私が使用する便利な機能の1つは、DataRow[columnName].ToString()常にnull以外の値を返すことです。データベースの値がNULLの場合、空の文字列を取得します。

  7. 開発者が例外時に自動ブレークを有効にしていない場合でも、開発者の注意を引く必要がある場合は、Debuggerオブジェクトを使用して自動的にブレークします。


#if DEBUG  
    if (Debugger.IsAttached)  
        Debugger.Break();  
#endif
  1. 複雑で見苦しいジェネリック型にエイリアスを付けることができるので、何度もコピーアンドペーストする必要はありません。また、そのタイプを1か所で変更できます。例えば、

    using ComplicatedDictionary = Dictionary<int, Dictionary<string, object>>;
    ComplicatedDictionary myDictionary = new ComplicatedDictionary();
于 2009-11-10T11:28:19.000 に答える
38

System.Enum など、拡張メソッドに特定のシステム クラスを使用すると非常に便利だと思います。以下のようなことができます...

[Flags]
public enum ErrorTypes : int {
    None = 0,
    MissingPassword = 1,
    MissingUsername = 2,
    PasswordIncorrect = 4
}

public static class EnumExtensions {

    public static T Append<T> (this System.Enum type, T value) where T : struct
    {
        return (T)(ValueType)(((int)(ValueType) type | (int)(ValueType) value));
    }

    public static T Remove<T> (this System.Enum type, T value) where T : struct
    {
        return (T)(ValueType)(((int)(ValueType)type & ~(int)(ValueType)value));
    }

    public static bool Has<T> (this System.Enum type, T value) where T : struct
    {
        return (((int)(ValueType)type & (int)(ValueType)value) == (int)(ValueType)value);
    }

}

...

//used like the following...

ErrorTypes error = ErrorTypes.None;
error = error.Append(ErrorTypes.MissingUsername);
error = error.Append(ErrorTypes.MissingPassword);
error = error.Remove(ErrorTypes.MissingUsername);

//then you can check using other methods
if (error.Has(ErrorTypes.MissingUsername)) {
    ...
}

もちろん、これは単なる例です-メソッドはもう少し作業を行うことができます...

于 2009-01-02T16:26:32.977 に答える
38

閉鎖

匿名デリゲートが 2.0 に追加されて以来、クロージャを開発できるようになりました。プログラマが使用することはめったにありませんが、コードをすぐに再利用できるなどの大きなメリットがあります。次のコードを検討してください。

bool changed = false;

if (model.Prop1 != prop1)
{
    changed = true;
    model.Prop1 = prop1;
}
if (model.Prop2 != prop2)
{
    changed = true;
    model.Prop2 = prop2;
}
// ... etc. 

上記の if ステートメントは、1 行のコードを除いて同様のコードを実行することに注意してください。つまり、異なるプロパティを設定します。これは次のように短縮できます。ここでは、さまざまなコード行がパラメーターとしてActionオブジェクトに入力され、適切な名前が付けられsetAndTagChangedます。

bool changed = false;
Action<Action> setAndTagChanged = (action) => 
{ 
    changed = true; 
    action(); 
};

if (model.Prop1 != prop1) setAndTagChanged(() => model.Prop1 = prop1);
if (model.Prop2 != prop2) setAndTagChanged(() => model.Prop2 = prop2);

2 番目のケースでは、クロージャーを使用するとchange、ラムダで変数のスコープを設定できます。これは、この問題にアプローチする簡潔な方法です。

別の方法は、別の使用されていない機能である「または等しい」二項代入演算子を使用することです。次のコードは、その方法を示しています。

private bool conditionalSet(bool condition, Action action)
{
    if (condition) action();
    return condition;
}

// ...

bool changed = false;
changed |= conditionalSet(model.Prop1 == prop1, () => model.Prop1 = prop1);
changed |= conditionalSet(model.Prop2 == prop2, () => model.Prop2 = prop2);
于 2008-12-24T18:10:36.670 に答える
36

列挙型を持つことができることは、int(デフォルト)以外の値を持ちます

public enum MyEnum : long
{
    Val1 = 1,
    Val2 = 2
}

また、その列挙型に任意の数値を割り当てることができるという事実:

MyEnum e = (MyEnum)123;
于 2008-08-14T22:31:26.180 に答える
36

私は今日、これについて知りました。C# を 5 年間使用しています。

名前空間エイリアス修飾子です:

extern alias YourAliasHere;

これを使用して、同じタイプの複数のバージョンをロードできます。これは、型の更新されたバージョンが古いコードでは機能しないが、新しいバージョンにアップグレードする必要がある、メンテナンスまたはアップグレードのシナリオで役立ちます。名前空間エイリアス修飾子を平手打ちすると、コンパイラはコードに両方の型を含めることができます。

于 2008-09-05T16:53:07.433 に答える
36

RealProxy を使用すると、既存の型に対して独自のプロキシを作成できます。

これは非常に高度な機能であり、他の人が使用しているのを見たことがありません。つまり、ほとんどの人にとってはあまり役に立たないということかもしれませんが、知っておくと便利なことの 1 つです。

基本的に、.NET RealProxyクラスを使用すると、別のタイプへの透過プロキシと呼ばれるものを作成できます。この場合の透明とは、プロキシされたターゲット オブジェクトのようにクライアントに完全に見えることを意味しますが、実際にはそうではありません。これは、RealProxy から派生したクラスのインスタンスです。

これにより、クライアントと、実際のターゲット オブジェクトで呼び出されるメソッドまたはプロパティとの間に、強力で包括的なインターセプトおよび「仲介」サービスを適用できます。この機能をファクトリ パターン (IoC など) と組み合わせると、実際のオブジェクトの代わりに透過的なプロキシを返すことができるため、実際のオブジェクトへのすべての呼び出しをインターセプトし、各メソッド呼び出しの前後にアクションを実行できます。実際、これは .NET がアプリ ドメイン、プロセス、およびマシンの境界を越えてリモート処理するために使用する機能そのものだと思います。.NET はすべてのアクセスをインターセプトし、シリアル化された情報をリモート オブジェクトに送信し、応答を受信して​​コードに返します。

これがどのように役立つかは、例によって明らかになるでしょう。私は、エンタープライズ アーキテクトとしての最後の仕事のために、部門全体の新しい WCF サービスの標準的な内部構成 (「スタック」) を指定する参照サービス スタックを作成しました。このモデルは、(たとえば) Foo サービスのデータ アクセス レイヤーが Foo のIDAL<Foo>: 作成、Foo の読み取り、Foo の更新、Foo の削除を実装することを義務付けていました。サービス開発者は、サービスに必要な DAL を見つけてロードする、提供された共通コード (私から) を使用しました。

IDAL<T> GetDAL<T>(); // retrieve data access layer for entity T

その会社のデータ アクセス戦略は、よくパフォーマンスの問題を抱えていました。アーキテクトとして、すべてのサービス開発者を監視して、パフォーマンスの高いデータ アクセス レイヤーを作成したことを確認することはできませんでした。しかし、GetDALファクトリ パターン内でできることは、要求された DAL への透過的なプロキシを作成し(共通サービス モデル コードが DLL を見つけてロードした後)、高性能タイミング API を使用して、任意のメソッドへのすべての呼び出しをプロファイリングすることでした。ダル。遅れている人をランク付けすることは、合計時間の降順で DAL 呼び出しのタイミングを並べ替えるだけです。開発プロファイリング (IDE など) に対するこの利点は、SLA を保証するために、運用環境でも実行できることです。

以下は、「エンティティ プロファイラー」用に私が書いたテスト コードの例です。これは、1 行で任意の型のプロファイリング プロキシを作成する一般的なコードでした。

[Test, Category("ProfileEntity")]
public void MyTest()
{
    // this is the object that we want profiled.
    // we would normally pass this around and call
    // methods on this instance.
    DALToBeProfiled dal = new DALToBeProfiled();

    // To profile, instead we obtain our proxy
    // and pass it around instead.
    DALToBeProfiled dalProxy = (DALToBeProfiled)EntityProfiler.Instance(dal);

    // or...
    DALToBeProfiled dalProxy2 = EntityProfiler<DALToBeProfiled>.Instance(dal);

    // Now use proxy wherever we would have used the original...
    // All methods' timings are automatically recorded
    // with a high-resolution timer
    DoStuffToThisObject(dalProxy);

    // Output profiling results
    ProfileManager.Instance.ToConsole();
}

繰り返しますが、これにより、ターゲット オブジェクトでクライアントによって呼び出されたすべてのメソッドとプロパティをインターセプトできます! RealProxy 派生クラスでは、Invokeをオーバーライドする必要があります。

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[SecurityPermission(SecurityAction.LinkDemand, 
    Flags = SecurityPermissionFlag.Infrastructure)] // per FxCop
public override IMessage Invoke(IMessage msg)
{
    IMethodCallMessage msgMethodCall = msg as IMethodCallMessage;
    Debug.Assert(msgMethodCall != null); // should not be null - research Invoke if this trips. KWB 2009.05.28

    // The MethodCallMessageWrapper
    // provides read/write access to the method 
    // call arguments. 
    MethodCallMessageWrapper mc =
        new MethodCallMessageWrapper(msgMethodCall);

    // This is the reflected method base of the called method. 
    MethodInfo mi = (MethodInfo)mc.MethodBase;

    IMessage retval = null;

    // Pass the call to the method and get our return value
    string profileName = ProfileClassName + "." + mi.Name;

    using (ProfileManager.Start(profileName))
    {
        IMessage myReturnMessage =
           RemotingServices.ExecuteMessage(_target, msgMethodCall);

        retval = myReturnMessage;
    }

    return retval;
}

.NET でできることは魅力的ではありませんか。唯一の制限は、ターゲットの型がMarshalByRefObjectから派生している必要があることです。これが誰かの役に立てば幸いです。

于 2010-06-29T05:18:36.120 に答える
35

任意のネストされたスコープ { }


1.より細かいスコーピング動作のために

{メンバー内の任意の場所}{中かっ​​このみを使用}{制御ステートメントなし}

void MyWritingMethod() {

    int sameAge = 35;


    { // scope some work
        string name = "Joe";
        Log.Write(name + sameAge.ToString());
    }


    { // scope some other work
        string name = "Susan";
        Log.Write(name + sameAge.ToString());
    }

    // I'll never mix up Joe and Susan again
}

大規模な、紛らわしい、または古風なメンバー (ただし、存在する必要はありません) の内部では、間違った変数名の使用を防ぐのに役立ちます。ものをより細かいレベルにスコープします。

2. コードの美化または視覚的なセマンティクスのため

たとえば、この XML 書き込みコードは、実際に生成された XML のインデント レベルに従います (つまり、Visual Studio はそれに応じてスコープ中かっこをインデントします)。

XmlWriter xw = new XmlWriter(..);

//<root>
xw.WriteStartElement("root");
{
    //<game>
    xw.WriteStartElement("game");
    {
        //<score>#</score>
        for (int i = 0; i < scores.Length; ++i) // multiple scores
            xw.WriteElementString("score", scores[i].ToString());

    }
    //</game>
    xw.WriteEndElement();
}
//</root>
xw.WriteEndElement();

3.「with」ステートメントを模倣する

(また、一時的な作業を主な範囲から除外する別の用途) Patrik
提供: C# で VB の "with-statement" を模倣するために使用されることがあります。

var somePerson = this.GetPerson();  // whatever 
{ 
    var p = somePerson; 
    p.FirstName = "John"; 
    p.LastName = "Doe"; 
    //... 
    p.City = "Gotham"; 
} 

目の肥えたプログラマー向け。

于 2010-03-22T20:05:06.127 に答える
34

非表示ではありませんが、多くの開発者は null 許容型で HasValue および Value プロパティを使用していないと思います。

        int? x = null;
        int y;
        if (x.HasValue)
            y = x.Value;
于 2008-08-18T23:47:06.157 に答える
33

私のお気に入りは

global::

一部のサードパーティ コード プロバイダーで名前空間の地獄から逃れるためのキーワード...

例:

global::System.Collections.Generic.List<global::System.String> myList =
    new global::System.Collections.Generic.List<global::System.String>();
于 2008-08-15T11:34:02.497 に答える
31

7ページすべてを読みましたが、次のページがありません。

String.Join

アイテムのリストを区切り文字付きの文字列に変換するためのforループをたくさん見てきました。セパレーターで開始したり、セパレーターで終了したりしないようにするのは常に苦痛です。組み込みのメソッドにより、これが簡単になります。

String.Join(",", new String[] { "a", "b", "c"});

コメントでTODO

実際にはC#の機能ではなく、VisualStudioの機能です。TODOでコメントを開始すると、そのコメントがVisual Studioタスクリストに追加されます([表示]-> [タスクリスト]。コメント)。

// TODO: Implement this!
throw new NotImplementedException();

拡張メソッドはジェネリックスに適合

拡張メソッドをジェネリックスと組み合わせることができます。このトピックの前半でヒントを考えたときに、特定のインターフェイスに拡張機能を追加できます。

public static void Process<T>(this T item) where T:ITest,ITest2 {}

Enumerable.Range

整数のリストが必要ですか?

Enumerable.Range(0, 15)

もう少し考えてみます...

于 2009-07-11T19:01:09.543 に答える
31

typedef

誰かが typedef を見逃していると投稿しましたが、このようにすることができます

using ListOfDictionary = System.Collections.Generic.List<System.Collections.Generic.Dictionary<string, string>>;

そしてそれを次のように宣言します

ListOfDictionary list = new ListOfDictionary();
于 2010-06-13T05:14:40.770 に答える
31

1 つの using ステートメントで複数のオブジェクトを「使用」できます。

using (Font f1= new Font("Arial", 10.0f), f2 = new Font("Arial", 10.0f))
{
    // Use f1 and f2.
}

これを行うことができるという回答が既にあることに注意してください。

using (Font f1= new Font("Arial", 10.0f))
using (Font f2 = new Font("Arial", 10.0f))
{    }

それは私のものとは異なります。

于 2009-09-12T19:47:40.967 に答える
31

string.Format()

Console.WriteLine("Product: {0,-7} Price: {1,5}", product1, price1);
Console.WriteLine("Product: {0,-7} Price: {1,5}", product2, price2);

生産する

代替テキスト

Prabir のブログから | 非表示の C# 機能

于 2010-05-27T03:10:14.313 に答える
30

私はキーワードcontinue が好きです。

ループで条件にヒットし、何もしたくない場合は、ループを進めるだけで、「続行;」に固執します。

例えば:

foreach(object o in ACollection)
{
  if(NotInterested)
     continue;
}
于 2008-09-08T12:49:17.587 に答える
28

ステートメントを使用したネスト

通常、次のようにします。

StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter()) {
    using (IndentedTextWriter itw = new IndentedTextWriter(sw)) {
        ... 
    }
}

しかし、私たちはこのようにそれを行うことができます:

StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter())
using (IndentedTextWriter itw = new IndentedTextWriter(sw)) {
    ... 
}
于 2008-09-01T05:03:20.607 に答える
28

私がめったに使用しないと思う私の個人的なお気に入りの2つ:

  1. スニペット(特に、Visual Studio 2008でさらに改善されたプロパティ用)
  2. ObsoleteAttribute _
于 2008-08-12T16:37:19.037 に答える
28

@lomaxx先日(私があなたのヒントを学んだのと同じ時間に)私が学んだのは、同じプロパティで異なるアクセスレベルを持つことができるということです:

public string Name { get; private set;}

そうすれば、クラス自体だけがNameプロパティを設定できます。

public MyClass(string name) { Name = name; }
于 2008-08-19T04:41:58.247 に答える
28

JavaScript のような無名インライン関数

文字列を返します:

var s = new Func<String>(() =>
{
    return "Hello World!";
})();

より複雑なオブジェクトを返します:

var d = new Func<Dictionary<Int32, String>>(() =>
{
    return new Dictionary<Int32, String>
    {
        { 0, "Foo" },
        { 1, "Bar" },
        { 2, "..." }
    };
})();

実際の使用例:

var tr = new TableRow();

tr.Cells.AddRange
(
    new[]
    {
        new TableCell { Text = "" },
        new TableCell { Text = "" },
        new TableCell { Text = "" },

        new TableCell
        {
            Text = new Func<String>(() =>
            {
                return @"Result of a chunk of logic, without having to define
                         the logic outside of the TableCell constructor";
            })()
        },

        new TableCell { Text = "" },
        new TableCell { Text = "" }
    }
);

注: インライン関数のスコープ内で変数名を再利用することはできません。


代替構文

// The one-liner
Func<Int32, Int32, String> Add = (a, b) => Convert.ToString(a + b);

// Multiple lines
Func<Int32, Int32, String> Add = (a, b) =>
{
    var i = a + b;

    return i.ToString();
};

// Without parameters
Func<String> Foo = () => "";

// Without parameters, multiple lines
Func<String> Foo = () =>
{
    return "";
};

文字列を短くして、横方向の省略記号を追加する...

Func<String, String> Shorten = s => s.Length > 100 ? s.Substring(0, 100) + "&hellip;" : s;
于 2009-09-09T11:31:54.323 に答える
27

1行でのオンデマンドフィールド初期化:

public StringBuilder Builder
{
    get { return _builder ?? (_builder = new StringBuilder()); }
}

C#が代入式をサポートしていることについてどう思うかわかりませんが、ねえ、それはそこにあります:-)

于 2008-11-18T16:16:26.043 に答える
27

静的フィールドをスレッドごとに一意にするためのThreadStaticAttributeもあるため、厳密に型指定されたスレッドローカルストレージを使用できます。

拡張メソッドがそれほど秘密ではない場合でも(LINQはそれらに基づいています)、ユーティリティヘルパーメソッドにとって拡張メソッドがどれほど有用で読みやすいかについてはそれほど明白ではない場合があります。

//for adding multiple elements to a collection that doesn't have AddRange
//e.g., collection.Add(item1, item2, itemN);
static void Add<T>(this ICollection<T> coll, params T[] items)
 { foreach (var item in items) coll.Add(item);
 }

//like string.Format() but with custom string representation of arguments
//e.g., "{0} {1} {2}".Format<Custom>(c=>c.Name,"string",new object(),new Custom())
//      result: "string {System.Object} Custom1Name"
static string Format<T>(this string format, Func<T,object> select, params object[] args)
 { for(int i=0; i < args.Length; ++i)
    { var x = args[i] as T;
      if (x != null) args[i] = select(x);
    }
   return string.Format(format, args);
 }
于 2008-08-17T21:13:24.393 に答える
27

宣言された変数の型を簡単に判断できます(私の答えから):

using System;
using System.Collections.Generic;

static class Program
{
    public static Type GetDeclaredType<T>(T x)
    {
        return typeof(T);
    }

    // Demonstrate how GetDeclaredType works
    static void Main(string[] args)
    {
        IList<string> iList = new List<string>();
        List<string> list = null;

        Console.WriteLine(GetDeclaredType(iList).Name);
        Console.WriteLine(GetDeclaredType(list).Name);
    }
}

結果:

IList`1
List`1

そしてその名前( 「Get variable name」から借用):

static void Main(string[] args)
{
    Console.WriteLine("Name is '{0}'", GetName(new {args}));
    Console.ReadLine();
}

static string GetName<T>(T item) where T : class
{
    var properties = typeof(T).GetProperties();
    return properties[0].Name;
}

結果:Name is 'args'

于 2009-11-24T13:15:08.260 に答える
27

コール スタックへのフル アクセス:

public static void Main()
{
  StackTrace stackTrace = new StackTrace();           // get call stack
  StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

  // write call stack method names
  foreach (StackFrame stackFrame in stackFrames)
  {
    Console.WriteLine(stackFrame.GetMethod().Name);   // write method name
  }
}

したがって、最初の関数を使用すると、自分がどの関数にいるかがわかります。ヘルパー トレース関数を作成している場合は、最後の関数の前に関数を使用すると、呼び出し元がわかります。

于 2008-10-10T16:22:40.903 に答える
26

C/C++ から移行するプログラマーは、これを見逃す可能性があります。

C# では、% (剰余演算子) が float で機能します。

于 2009-08-07T06:44:19.817 に答える
26

これは実際には C# の隠し機能ではありませんが、最近WeakReference クラスを発見し、それに圧倒されました (これは、私の特定の問題の解決策を見つけるのに役立ったという事実によってバイアスがかかっている可能性がありますが...)

于 2008-08-18T14:43:56.020 に答える
26

Environment.UserInteractiveプロパティ。

UserInteractive プロパティは、Windows プロセス、またはユーザー インターフェイスなしで実行される IIS などのサービスに対して false を報告します。このプロパティが false の場合、モーダル ダイアログまたはメッセージ ボックスを表示しないでください。ユーザーが対話するためのグラフィカル ユーザー インターフェイスがないためです。

于 2008-10-08T07:45:04.330 に答える
26

AppDomain.UnhandledException イベントも非表示の候補です。

このイベントは、キャッチされていない例外を通知します。これにより、アプリケーションは、システムのデフォルト ハンドラがユーザーに例外を報告してアプリケーションを終了する前に、例外に関する情報をログに記録できます。アプリケーションの状態に関する十分な情報が利用可能な場合は、後で復元するためにプログラム データを保存するなど、他のアクションを実行できます。例外が処理されない場合、プログラム データが破損する可能性があるため、注意が必要です。

このサイトでも、なぜアプリケーションが起動しないのか、なぜクラッシュしたのかなど、多くの人が疑問に思っていることがわかります。このAppDomain.UnhandledExceptionイベントは、少なくともアプリケーションの理由をログに記録する可能性を提供するため、このような場合に非常に役立ちます。失敗。

于 2010-06-30T04:20:12.973 に答える
25

C#?? null合体演算子-

実際には隠されていませんが、めったに使用されません。おそらく、多くの開発者が条件付きを見ると1マイル走るからでしょう。演算子なので、これを見ると2つ実行されます。使用済み:

string mystring = foo ?? "foo was null"

それよりも

string mystring;
if (foo==null)
    mystring = "foo was null";
else
    mystring = foo;
于 2008-08-26T12:54:41.083 に答える
25

#if DEBUGプリプロセッサ ディレクティブ。これは、テストとデバッグに役立ちます (ただし、私は通常、単体テスト ルートを使用することを好みます)。

string customerName = null;
#if DEBUG
  customerName = "Bob"
#endif

Visual Studio が「デバッグ」モードでコンパイルするように設定されている場合にのみ、コード ブロックが実行されます。そうしないと、コード ブロックはコンパイラによって無視されます (Visual Studio ではグレー表示されます)。

于 2008-08-26T22:19:01.507 に答える
25

string.Join を使用して、区切り記号を使用して文字列を結合している人は見つかりませんでした。誰もが同じ醜い for ループを書き続ける

var sb = new StringBuilder();
var count = list.Count();
for(int i = 0; i < count; i++)
{
  if (sb.Length > 0) sb.Append(seperator);
  sb.Append(list[i]);
}

return sb.ToString();

それ以外の

return string.Join(separator, list.ToArray());
于 2010-01-25T13:55:03.170 に答える
24

部分メソッド

Charlie Calvert が彼のブログで部分メソッドについて説明しています

Scott Cate はここに素晴らしい部分メソッドのデモを持っています

  1. コード生成クラスの拡張性のポイント (LINQ to SQL、EF)
  2. 実装されていない場合、dll にコンパイルされません (.NET Reflector で確認してください)。
于 2008-08-19T15:23:12.040 に答える
24

trueおよびfalse演算子は本当に奇妙です。

より包括的な例は、ここにあります。

編集:関連するSOの質問がありますWhat's the false operator in C# good for?

于 2008-08-28T12:55:57.850 に答える
24

TypedReference の文書化されていないクラスに関連する C# には、実際には隠されたキーワードと機能がいくつかあります。次のキーワードは文書化されていません。

  • __makeref
  • __reftype
  • __refvalue
  • __arglist

使用例:

// Create a typed reference
int i = 1;
TypedReference tr1 = __makeref(i);
// Get the type of a typed reference
Type t = __reftype(tr1);
// Get the value of a typed referece
int j = __refvalue(tr1, int); 
// Create a method that accepts and arbitrary number of typed references
void SomeMethod(__arglist) { ...
// Call the method
int x = 1;
string y = "Foo";
Object o = new Object();
SomeMethod(__arglist(x,y,o));
// And finally iterate over method parameters
void SomeMethod(__arglist) {
    ArgIterator ai = new ArgIterator(__arglist);
while(ai.GetRemainingCount() >0)
{
      TypedReference tr = ai.GetNextArg();
      Console.WriteLine(TypedReference.ToObject(tr));
}}
于 2008-09-05T07:49:27.087 に答える
23

この機能について知っている開発者はほとんどいないことがわかりました。

なんらかのインターフェイス (この値型によって実装される) を介して値型変数を操作するメソッドが必要な場合、メソッド呼び出し中のボックス化を回避するのは簡単です。

コード例:

using System;
using System.Collections;

interface IFoo {
    void Foo();
}
struct MyStructure : IFoo {
    public void Foo() {
    }
}
public static class Program {
    static void MethodDoesNotBoxArguments<T>(T t) where T : IFoo {
        t.Foo();
    }
    static void Main(string[] args) {
        MyStructure s = new MyStructure();
        MethodThatDoesNotBoxArguments(s);
    }
}

IL コードにはボックスの説明は含まれていません。

.method private hidebysig static void  MethodDoesNotBoxArguments<(IFoo) T>(!!T t) cil managed
{
  // Code size       14 (0xe)
  .maxstack  8
  IL_0000:  ldarga.s   t
  IL_0002:  constrained. !!T
  IL_0008:  callvirt   instance void IFoo::Foo()
  IL_000d:  ret
} // end of method Program::MethodDoesNotBoxArguments

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       15 (0xf)
  .maxstack  1
  .locals init ([0] valuetype MyStructure s)
  IL_0000:  ldloca.s   s
  IL_0002:  initobj    MyStructure
  IL_0008:  ldloc.0
  IL_0009:  call       void Program::MethodDoesNotBoxArguments<valuetype MyStructure>(!!0)
  IL_000e:  ret
} // end of method Program::Main

Richter, J. CLR via C#、第 2 版、第 14 章: インターフェイス、ジェネリックとインターフェイス制約に関するセクションを参照してください。

別の質問に対する私の回答も参照してください。

于 2009-11-30T15:37:31.573 に答える
22

ほぼすべてのクールなものが言及されています。これが有名かどうかは不明

C# プロパティ/フィールド コンストラクターの初期化:

var foo = new Rectangle() 
{ 
    Fill = new SolidColorBrush(c), 
    Width = 20, 
    Height = 20 
};

これにより、長方形が作成され、リストされたプロパティが設定されます。

おかしなことに気付きました。プロパティ リストの最後にカンマを付けても、構文エラーにはなりません。したがって、これも有効です。

var foo = new Rectangle() 
{ 
    Fill = new SolidColorBrush(c), 
    Width = 20, 
    Height = 20,
};
于 2008-08-18T23:08:35.830 に答える
21

このスレッドのタイトルは、「既にすべてを知っていると思っているにもかかわらず、最近まで C# について知らなかったこと」というタイトルにする必要があることに基づいて、私の個人的な機能は非同期デリゲートです。

Jeff Richter の C#/CLR の本 (すばらしい本です。.NET を使用しているすべての人は読むべきです) を読むまで、/を使用して任意のデリゲートを呼び出せることを知りませんでした。私は多くの呼び出しを行う傾向があります (デリゲートが内部で行っていることとよく似ていると思います) が、標準化された参加/ランデブー パターンの追加が非常に役立つ場合があります。BeginInvokeEndInvokeThreadPool.QueueUserWorkItemBeginInvoke

于 2008-08-13T08:29:09.287 に答える
21

何人かがブロックの使用について言及していますが、ブロックは人々が認識しているよりもはるかに便利だと思います。それらを貧乏人の AOP ツールと考えてください。コンストラクターで状態をキャプチャし、それをDispose()メソッドで復元する単純なオブジェクトが多数あります。これにより、機能の一部をusingブロックでラップし、最後に状態が確実に復元されるようにすることができます。例えば:

using(new CursorState(this, BusyCursor));
{
    // Do stuff
}

CursorStateは、フォームで使用されている現在のカーソルを取得し、提供されたカーソルを使用するようにフォームを設定します。最後に、元のカーソルを復元します。たとえば、リフレッシュする前にグリッド上の選択と現在の行をキャプチャするなど、このようなことをたくさん行います。

于 2008-11-18T20:51:07.910 に答える
21

イベント ハンドラーに関するもう 1 つの注意事項: 次のように raise 拡張メソッドを簡単に作成できます。

public static class EventExtensions {
    public static void Raise<T>(this EventHandler<T> @event, 
                                object sender, T args) where T : EventArgs {
        if(@event!= null) {
            @event(sender, args);
        }
    }
}

次に、それを使用してイベントを発生させることができます。

public class MyImportantThing {
    public event EventHandler<MyImportantEventEventArgs> SomethingHappens;
    ...
    public void Bleh() {
        SomethingHappens.Raise(this, new MyImportantEventEventArgs { X=true });
    }
}

この方法には、( を使用してEventHandler<>) コーディング標準を強制するという追加の利点があります。

まったく同じ関数を何度も何度も書いても意味がありません。おそらく、C# の次のバージョンでは、最終的にInlineAttribute拡張メソッドに配置できる があり、コンパイラがメソッド定義をインライン化するようになります (これにより、この方法がほぼ標準になり、最速になります)。

編集: コメントに基づいて拡張メソッド内の一時変数を削除しました

于 2010-06-22T16:12:29.493 に答える
20

投稿が遅くなってしまったことをお詫びします。StackOverflowを初めて使用するため、以前の機会を逃しました。

EventHandler<T>これは、十分に活用されていないフレームワークの優れた機能だと思います。

私が出会ったほとんどのC#開発者は、カスタムイベントを定義するときに、カスタムイベントハンドラーデリゲートを定義しますが、これはもはや必要ありません。

それ以外の:

public delegate void MyCustomEventHandler(object sender, MyCustomEventArgs e);

public class MyCustomEventClass 
{
    public event MyCustomEventHandler MyCustomEvent;
}

行ってもいい:

public class MyCustomEventClass 
{
    public event EventHandler<MyCustomEventArgs> MyCustomEvent;
}

これははるかに簡潔であり、さらに、イベントを含むクラスまたはEventArgs派生クラスの.csファイルにデリゲートを配置するかどうかというジレンマに陥ることはありません。

于 2009-09-23T09:00:29.407 に答える
20

私はこのパーティーに遅れているので、私の最初の選択はすでに行われています。しかし、私はまだ誰もこの宝石について言及していませんでした:

.NETFrameworkの並列拡張

Parallel.ForまたはforeachをParallel.ForEachに置き換えるなどの機能があります。


並列サンプル:
あなたの意見では、1秒間にいくつのCLRオブジェクトを作成できますか? ここに画像の説明を入力してください
休閑の例を参照してください:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ObjectInitSpeedTest
{
   class Program
   {
       //Note: don't forget to build it in Release mode.
       static void Main()
       {
           normalSpeedTest();           
           parallelSpeedTest();

           Console.ForegroundColor = ConsoleColor.White;
           Console.WriteLine("Press a key ...");
           Console.ReadKey();
       }

       private static void parallelSpeedTest()
       {
           Console.ForegroundColor = ConsoleColor.Yellow;
           Console.WriteLine("parallelSpeedTest");

           long totalObjectsCreated = 0;
           long totalElapsedTime = 0;

           var tasks = new List<Task>();
           var processorCount = Environment.ProcessorCount;

           Console.WriteLine("Running on {0} cores", processorCount);

           for (var t = 0; t < processorCount; t++)
           {
               tasks.Add(Task.Factory.StartNew(
               () =>
               {
                   const int reps = 1000000000;
                   var sp = Stopwatch.StartNew();
                   for (var j = 0; j < reps; ++j)
                   {
                       new object();
                   }
                   sp.Stop();

                   Interlocked.Add(ref totalObjectsCreated, reps);
                   Interlocked.Add(ref totalElapsedTime, sp.ElapsedMilliseconds);
               }
               ));
           }

           // let's complete all the tasks
           Task.WaitAll(tasks.ToArray());

           Console.WriteLine("Created {0:N} objects in 1 sec\n", (totalObjectsCreated / (totalElapsedTime / processorCount)) * 1000);
       }

       private static void normalSpeedTest()
       {
           Console.ForegroundColor = ConsoleColor.Green;
           Console.WriteLine("normalSpeedTest");

           const int reps = 1000000000;
           var sp = Stopwatch.StartNew();
           sp.Start();
           for (var j = 0; j < reps; ++j)
           {
               new object();
           }
           sp.Stop();

           Console.WriteLine("Created {0:N} objects in 1 sec\n", (reps / sp.ElapsedMilliseconds) * 1000);
       }
   }
}
于 2008-08-27T21:05:41.940 に答える
20
string.Empty

幻想的ではないことはわかっていますが(ばかげて奇妙です)、「」の代わりに常に使用しています。

そして、誰かがそこにあると言うまで、それはかなりうまく隠されています.

于 2010-06-30T09:24:46.087 に答える
20

私が気に入っている素晴らしいクラスの 1 つはSystem.Xml.XmlConvert、xml タグから値を読み取るために使用できるクラスです。特に、xml 属性または要素からブール値を読み取る場合は、

bool myFlag  = System.Xml.XmlConvert.ToBoolean(myAttribute.Value);

注: XML のブール型は有効な値として「true」と「false」に加えて 1 と 0 を受け入れるため、この場合に文字列比較を使用するとエラーが発生しやすくなります。

于 2008-12-05T11:10:09.463 に答える
20

属性ターゲット

誰もが一度は見たことがあるでしょう。基本的に、これを見ると:

[assembly: ComVisible(false)]

その属性の「assembly:」部分がターゲットです。この場合、属性はアセンブリに適用されますが、他にもあります。

[return: SomeAttr]
int Method3() { return 0; } 

このサンプルでは、​​属性が戻り値に適用されます。

于 2009-06-02T07:20:56.077 に答える
20

IObservableはどうですか?

ほとんどの人がIEnumerableを知っていますが、彼らの数学的双対は未知の IObservable のようです。.NET 4 で新しくなったためかもしれません。

それが行うことは、(列挙可能なような) 情報をプルする代わりに、オブザーバブルのサブスクライバーに情報をプッシュすることです。

Rx 拡張機能と共に、イベントの処理方法が変わります。それがどれほど強力かを説明するために、ここで非常に短い例を確認してください。

于 2010-04-21T15:41:05.063 に答える
20

当たり前のように思えるかもしれませんが、Object.Equalsメソッド (2 つの引数を持つ静的メソッド) について言及したいと思います。

多くの人がそれについて知らないか、そこにあることを忘れていると確信していますが、場合によっては本当に役立つことがあります. たとえば、2 つのオブジェクトの等価性を比較したい場合、それらが null かどうかはわかりません。そのようなことを何回書きましたか:

if ((x == y) || ((x != null && y != null) && x.Equals(y)))
{
    ...
}

あなたが書くことができるとき:

if (Object.Equals(x, y))
{
    ...
}

(Object.Equals実際には、最初のコード サンプルとまったく同じように実装されます)

于 2010-05-25T14:09:06.777 に答える
19

C#3.0のLINQクエリ内包表記は、 Haskellの本格的な一項内包表記です(実際、Haskellの設計者の1人によって設計されました)。これらは、「LINQパターン」に従う任意のジェネリック型で機能し、純粋なモナディック関数スタイルで記述できます。つまり、すべての変数が不変である(使用した変数がsとsのみであるかようIDisposableIEnumerableforeachステートメント)。これは、変数宣言を使用場所の近くに維持し、副作用がある場合はすべての副作用が明示的に宣言されていることを確認するのに役立ちます。

 interface IFoo<T>
  { T Bar {get;}
  }

 class MyFoo<T> : IFoo<T> 
  { public MyFoo(T t) {Bar = t;}
    public T Bar {get; private set;} 
  }

 static class Foo 
  { public static IFoo<T> ToFoo<T>(this T t) {return new MyFoo<T>(t);}

    public static void Do<T>(this T t, Action<T> a) { a(t);}

    public static IFoo<U> Select<T,U>(this IFoo<T> foo, Func<T,U> f) 
     { return f(foo.Bar).ToFoo();
     }
  }

 /* ... */

 using (var file = File.OpenRead("objc.h"))
 { var x = from f in file.ToFoo()
           let s = new Scanner(f)
           let p = new Parser {scanner = s}
           select p.Parse();

   x.Do(p => 
    { /* drop into imperative code to handle file 
         in Foo monad if necessary */      
    });

 }
于 2009-01-01T16:10:01.197 に答える
19

隠されているわけではありませんが、便利です。enumwithがある場合はflags、左シフトを使用して物事を明確にすることができます。例えば

[Flags]
public enum ErrorTypes {
    None              = 0,
    MissingPassword   = 1 << 0,
    MissingUsername   = 1 << 1,
    PasswordIncorrect = 1 << 2 
}
于 2010-06-22T12:55:40.147 に答える
19

多くの人が の機能を再現していますNullable<T>.GetValueOrDefault(T)

于 2008-08-20T15:00:30.173 に答える
18

私のお気に入りの属性: InternalsVisibleTo

アセンブリ レベルでは、別のアセンブリが内部を参照できることを宣言できます。テスト目的では、これは非常に素晴らしいことです。

これを AssemblyInfo.cs または同等のものに貼り付けると、テスト アセンブリは、テストが必要なすべての内部要素に完全にアクセスできます。

[assembly: InternalsVisibleTo("MyLibrary.Test, PublicKey=0024...5c042cb")]

ご覧のとおり、テスト対象アセンブリの信頼を得るには、テスト アセンブリに厳密な名前を付ける必要があります。

.Net Framework 2.0+、Compact Framework 2.0+、および XNA Framework 1.0+ で利用できます。

于 2009-04-17T07:09:13.487 に答える
17

空の IEnumerable を返す必要がありますか?

public IEnumerable<T> GetEnumerator(){
  yield break;
}
于 2009-11-12T19:43:24.913 に答える
17

私は SQL クエリに @ 文字を使用するのが大好きです。これにより、各行を文字列区切り記号で囲む必要なく、SQL が適切にフォーマットされた状態に保たれます。

string sql = @"SELECT firstname, lastname, email
               FROM users
               WHERE username = @username AND password = @password";
于 2008-08-28T16:17:15.883 に答える
17

同じ完全修飾型名を持つ 2 つのバージョンのアセンブリを参照するためのextern エイリアスキーワード。

于 2008-09-01T13:21:10.630 に答える
16

C#名には、次のような任意のUnicode文字を使用できます。

public class MyClass
{
    public string Hårføner()
    {
        return "Yes, it works!";
    }
}

Unicodeエスケープを使用することもできます。これは上記と同等です。

public class MyClass
{
    public string H\u00e5rføner()
    {
        return "Yes, it (still) works!";
    }
}
于 2008-11-19T16:28:25.427 に答える
16

Enum に色を格納できます。

public enum MyEnumColors : uint
{
    Normal          = 0xFF9F9F9F,
    Active          = 0xFF8EA98A,
    Error           = 0xFFFF0000
}
于 2010-02-14T18:52:49.937 に答える
15

列挙型のFlagsAttributeはどうですか?それはあなたがビット単位の操作を実行することを可能にします....NETでビット単位の操作をうまく行う方法を見つけるために私は永遠にかかりました。

于 2008-08-22T03:55:51.533 に答える
15

"~" 演算子を FlagAttribute と enum で
使用する ときどき、Flag 属性を enum で使用して、列挙型でビット単位の操作を実行します。

 [Flags]
 public enum Colors
 {
    None  = 0,
    Red   = 1,
    Blue  = 2,
    White = 4,
    Black = 8,
    Green = 16,
    All   = 31 //It seems pretty bad...
 }

列挙型のオプション「All」の値が非常に奇妙であることに注意してください。
その代わりに、フラグ付き列挙型で「~」演算子を使用できます。

 [Flags]
 public enum Colors
 {
    None  = 0,
    Red   = 1,
    Blue  = 2,
    White = 4,
    Black = 8,
    Green = 16,
    All   = ~0 //much better now. that mean 0xffffffff in default.
 }
于 2010-03-16T15:37:04.987 に答える
15

基本クラスのビューステートに永続化されたジェネリック パラメーター オブジェクトが必要になることがよくあります。

public abstract class BaseListControl<ListType,KeyType,ParameterType>
                 : UserControl 
                 where ListType : BaseListType
                 && ParameterType : BaseParameterType, new
{

    private const string viewStateFilterKey = "FilterKey";

    protected ParameterType Filters
    {
        get
        {
            if (ViewState[viewStateFilterKey] == null)
                ViewState[viewStateFilterKey]= new ParameterType();

            return ViewState[viewStateFilterKey] as ParameterType;
        }
        set
        {
            ViewState[viewStateFilterKey] = value;
        }
    }

}

使用法:

private void SomeEventHappened(object sender, EventArgs e)
{
    Filters.SomeValue = SomeControl.SelectedValue;
}

private void TimeToFetchSomeData()
{
    GridView.DataSource = Repository.GetList(Filters);
}

「where ParameterType : BaseParameterType, new」を使用したこの小さなトリックにより、実際に機能します。

基本クラスでこのプロパティを使用すると、ページングの処理を自動化したり、フィルター値を設定してグリッドビューをフィルター処理したり、並べ替えを非常に簡単にしたりできます。

私は本当に、ジェネリックは悪者の手に渡れば非常に強力な獣になる可能性があると言っているだけです.

于 2008-08-12T17:29:29.307 に答える
15

定款_

このステートメントは、ガベージ コレクターが可動変数を再配置するのを防ぎます。Fixed を使用して、固定サイズのバッファーを作成することもできます。

fixed ステートメントは、マネージド変数へのポインターを設定し、ステートメントの実行中にその変数を "固定" します。

スタックアロク

stackalloc は、スタックにメモリ ブロックを割り当てます。

于 2010-06-30T18:09:05.607 に答える
15

また、便利ですが、一般的には使用されません: Constrained Execution Regions

BCL チームのブログからの引用:

制約付き実行領域 (CER) は、開発者がコードを記述して一貫性を維持できるようにするために存在します。CLR は、開発者のコ​​ードが正しいことを保証しませんが、CLR は、実行時に発生するすべての障害ポイント (つまり、非同期例外) を、コードの実行前または完了後にホイストします。開発者が CER に入れることができるものに対する制約と組み合わせると、これらは、コードが実行されるかどうかについて強力な保証を行う便利な方法です。CER は熱心に準備されています。つまり、CER を見ると、静的に検出可能なコール グラフで見つかったコードを熱心に JIT します。CLR のホストがスタック オーバーフローを気にしている場合は、ある程度のスタック スペースも調査します (ただし、任意のメソッドに対して十分なスタック スペースがない可能性があります*)。

アトミックな方法でデータ構造の複数のフィールドを編集する場合に便利です。そのため、オブジェクトにトランザクションがあると役立ちます。

また、 CriticalFinalizerObjectは隠されているようです (少なくとも安全でないコードを書いていない人)。CriticalFinalizerObject は、ガベージ コレクションがファイナライザーを実行することを保証します。割り当て時に、ファイナライザとそのコール グラフが事前に準備されます。

于 2010-06-29T06:12:32.977 に答える
14

カスタム属性を定義するときは、[MyAttAttribute]または[MyAtt]で使用できます。両方の書き込みにクラスが存在する場合、コンパイルエラーが発生します。

@特殊文字を使用して、それらを区別できます。

[AttributeUsage(AttributeTargets.All)]
public class X: Attribute
{}

[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}

[X]      // Error: ambiguity
class Class1 {}

[XAttribute]   // Refers to XAttribute
class Class2 {}

[@X]      // Refers to X
class Class3 {}

[@XAttribute]   // Refers to XAttribute
class Class4 {}
于 2009-09-12T19:26:18.997 に答える
14

1組の角かっこに複数の属性を入れることができます。

    [OperationContract, ServiceKnownType(typeof(Prism)), ServiceKnownType(typeof(Cuboid))]
    Shape GetShape();
于 2010-07-03T17:31:40.200 に答える
14

クラスがINotifyPropertyChangedを実装し、オブジェクト (ViewModel) の複数のバインドされたプロパティが変更されたことをバインディング システム (WPF、Silverlight など) に通知したい場合は、nullまたはString.Emptyで PropertyChanged-Event を発生させることができます。

これは MSDN に文書化されていますが、コード例や記事ではこの可能性について説明していないことがよくあります。とても便利だと思いました。

public class BoundObject : INotifyPropertyChanged {

    private int _value;
    private string _text;

    public event PropertyChangedEventHandler PropertyChanged;

    public int Value {
        get {
            return _value;
        }
        set {
            if (_value != value) {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }

    public string Text {
        get {
            return _text;
        }
        set {
            if (_text != value) {
                _text = value;
                OnPropertyChanged("Text");
            }
        }
    }

    public void Init(){
        _text = "InitialValue";
        _value = 1;
        OnPropertyChanged(string.Empty);
    }

    public void Reset() {
        _text = "DefaultValue";
        _value = 0;
        OnPropertyChanged(string.Empty);
    }

    private void OnPropertyChanged(string propertyName) {
        PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);

        if (PropertyChanged != null) {
            PropertyChanged(this, e);
        }
    }
}
于 2010-04-22T07:40:51.540 に答える
14

エンドリージョンにラベルを付けています...

#region stuff1
 #region stuff1a
 //...
 #endregion stuff1a
#endregion stuff1
于 2008-10-03T05:57:04.743 に答える
14

条件付き属性

特定の条件下で、属性でマークされたメソッドへの呼び出しを省略するようにコンパイラーに指示できます (#define)。

メソッド呼び出しが省略されているという事実は、そのパラメーターが評価されないことも意味します。これは非常に便利で、Debug.Assert() で高価な検証関数を呼び出すことができるため、リリース ビルドが遅くなる心配はありません。

于 2008-08-29T21:28:19.343 に答える
14

ここ Stack Overflow で初めて学んだ機能の 1 つは、戻りパラメーターに属性を設定する機能です。

[AttributeUsage( AttributeTargets.ReturnValue )]
public class CuriosityAttribute:Attribute
{
}

public class Bar
{
    [return: Curiosity]
    public Bar ReturnANewBar()
    {
        return new Bar();
    }
}

これは本当に私にとって隠された機能でした:-)

于 2008-09-29T16:34:13.247 に答える
13

ファクトリメソッドの型推論

これがすでに投稿されているかどうかはわかりません(最初の投稿をスキャンしましたが、見つかりませんでした)。

これは、(タプルをシミュレートするための)このクラスがあると仮定して、これを可能にするすべての言語機能を示すために、例を示して最もよく示されています。

public class Tuple<V1, V2> : Tuple
{
    public readonly V1 v1;
    public readonly V2 v2;

    public Tuple(V1 v1, V2 v2)
    {
      this.v1 = v1;
      this.v2 = v2;
    }
}

誰もがそのインスタンスを作成する方法を知っています。たとえば、次のようになります。

Tuple<int, string> tup = new Tuple<int, string>(1, "Hello, World!");

厳密にはロケット科学ではありませんが、もちろん、変数の型宣言を次のようにvarに変更できます。

var tup = new Tuple<int, string>(1, "Hello, World!");

まだよく知られていますが、少し逸脱するために、型パラメーターを使用した静的メソッドがあります。これは、誰もがよく知っている必要があります。

public static void Create<T1, T2>()
{
    // stuff
}

これを呼び出すことは、やはり一般的な知識であり、次のように行われます。

Create<float, double>();

ほとんどの人が知らないのは、ジェネリックメソッドの引数に必要なすべての型が含まれている場合、それらを推測できることです。たとえば、次のようになります。

public static void Create<T1, T2>(T1 a, T2 b)
{
    // stuff
}

これらの2つの呼び出しは同じです。

Create<float, string>(1.0f, "test");
Create(1.0f, "test");

T1とT2は、渡した引数から推測されるためです。この知識をvarキーワードと組み合わせると、次のような静的メソッドを使用して2番目の静的クラスを追加できます。

public abstract class Tuple
{
    public static Tuple<V1, V2> Create<V1, V2>(V1 v1, V2 v2)
    {
        return new Tuple<V1, V2>(v1, v2);
    }
}

この効果を達成する:

var tup = Tuple.Create(1, "Hello, World!");

つまり、変数「tup」の型、「Create」の型パラメーター、および「Create」の戻り値はすべて、Createに引数として渡す型から推測されます。

完全なコードは次のようになります。

public abstract class Tuple
{
    public static Tuple<V1, V2> Create<V1, V2>(V1 v1, V2 v2)
    {
        return new Tuple<V1, V2>(v1, v2);
    }
}

public class Tuple<V1, V2> : Tuple
{
    public readonly V1 v1;
    public readonly V2 v2;

    public Tuple(V1 v1, V2 v2)
    {
        this.v1 = v1;
        this.v2 = v2;
    }
}

// Example usage:
var tup = Tuple.Create(1, "test");

これにより、どこでも完全に型推論されたファクトリメソッドが得られます!

于 2009-11-20T14:57:05.713 に答える
13

ラムダ式

Func<int, int, int> add = (a, b) => (a + b);

あいまいな文字列形式

Console.WriteLine("{0:D10}", 2); // 0000000002

Dictionary<string, string> dict = new Dictionary<string, string> { 
    {"David", "C#"}, 
    {"Johann", "Perl"}, 
    {"Morgan", "Python"}
};

Console.WriteLine( "{0,10} {1, 10}", "Programmer", "Language" );

Console.WriteLine( "-".PadRight( 21, '-' ) );

foreach (string key in dict.Keys)
{
    Console.WriteLine( "{0, 10} {1, 10}", key, dict[key] );             
}
于 2008-08-13T18:47:41.473 に答える
13

これを使用するのはどうですか:

#if DEBUG
            Console.Write("Debugging");
#else
            Console.Write("Final");
#endif

DEBUG を定義してソリューションをコンパイルすると、「Debugging」が出力されます。

コンパイルが Release に設定されている場合、「Final」と表示されます。

于 2008-11-19T16:58:38.097 に答える
13

FlagsAttribute は、列挙型を使用してビットマスクを作成する場合の小さいながらも優れた機能です。

[Flags]
public enum ConfigOptions
{
    None    = 0,
    A       = 1 << 0,
    B       = 1 << 1,
    Both    = A | B
}

Console.WriteLine( ConfigOptions.A.ToString() );
Console.WriteLine( ConfigOptions.Both.ToString() );
// Will print:
// A
// A, B
于 2009-06-05T18:43:55.447 に答える
13

最近になるまで、「使用中」のブロックに本当に感謝し始めていませんでした。彼らは物事をもっときれいにします:)

于 2008-08-15T14:51:42.590 に答える
13

拡張メソッドは既存のコードや編集できないコードに必要な機能を追加できるため、拡張メソッドの大ファンになりつつあります。私が今行っているすべてのことに追加するお気に入りの 1 つは、string.IsNullOrEmpty() です。

public static class Strings
{
    public static bool IsNullOrEmpty(this string value)
    {
        return string.IsNullOrEmpty(value);
    }
}

これにより、このようにコードを少し短くすることができます

var input = Console.ReadLine();
if (input.IsNullOrEmpty())
{
    Console.WriteLine("try again");
}
于 2009-07-30T04:23:58.397 に答える
12

switch-を通り抜けるcaseには、 a にコードを含めないcase(「 」を参照) かcase 0、特別なgoto case(「 」を参照case 1) またはgoto default(「 」を参照case 2) フォームを使用します。

switch (/*...*/) {
    case 0: // shares the exact same code as case 1
    case 1:
        // do something
        goto case 2;
    case 2:
        // do something else
        goto default;
    default:
        // do something entirely different
        break;
}
于 2008-09-18T06:08:15.720 に答える
12

私が考えることができるカップル:

[field: NonSerialized()]
public EventHandler event SomeEvent;

これにより、イベントがシリアル化されなくなります。「field:」は、属性をイベントのバッキング フィールドに適用する必要があることを示します。

もう 1 つのあまり知られていない機能は、追加/削除イベント ハンドラーのオーバーライドです。

public event EventHandler SomeEvent
{
    add
    {
        // ...
    }

    remove
    {
        // ...
    }
}
于 2009-11-30T17:41:12.223 に答える
12

私が長い間見逃していたもの: 文字列を比較することができます

"string".equals("String", StringComparison.InvariantCultureIgnoreCase)

代わりに:

"string".ToLower() == "String".ToLower();
于 2008-11-04T23:30:41.453 に答える
11

デリゲート構文は、C# の後続のバージョンで進化してきましたが、覚えるのが難しいと感じています。幸いなことにAction<>Func<>デリゲートは簡単に覚えられます。

例えば:

  • Action<int>単一の int 引数を取り、void を返すデリゲート メソッドです。
  • Func<int> 引数を取らず、int を返すデリゲート メソッドです。
  • Func<int, bool>単一の int 引数を取り、bool を返すデリゲート メソッドです。

これらの機能は、.NET フレームワークのバージョン 3.5 で導入されました。

于 2008-12-03T04:45:34.577 に答える
11

で拡張メソッドを呼び出すことができますnull。これにより aNullReferenceExceptionがスローされることはありません。

適用例: で呼び出されたときに空の文字列を返す、ToString()calledの代替を定義できます。ToStringOrEmpty()null

于 2009-07-02T00:34:17.423 に答える
11

宣言されたクラスと 1 つ以上の任意のクラスとの間implicitでユーザー定義の型変換を実行するための演算子があります。explicitこのimplicit演算子は、代入演算子のオーバーロードのシミュレーションを効果的に可能にします。これは、C++ などの言語では可能ですが、C# では可能ではありません。

あまり見かけない機能のようですが、実際にはLINQ to XML ( ) ライブラリで使用されており、暗黙的に文字列をオブジェクトSystem.Xml.Linqに変換できます。XName例:

XName tagName = "x:Name";

この機能は、C# で多重継承をシミュレートする方法に関するこの記事で発見しました。

于 2008-09-23T14:44:29.203 に答える
11

単純な古い .NET 2.0 上のオブジェクトに LINQ を使用できるという事実が気に入っています (つまり、.NET 3.5 をどこにでもインストールする必要はありません)。必要なのは、すべてのクエリ演算子拡張メソッドの実装だけです - LINQBridgeを参照してください

于 2008-08-14T10:59:21.430 に答える
11

メソッド引数が 2 つのインターフェイスを実装しているかどうかをチェックする (コンパイル時に) ジェネリックを使用できます。

interface IPropA 
{
    string PropA { get; set; } 
}

interface IPropB 
{
    string PropB { get; set; }
}

class TestClass 
{
    void DoSomething<T>(T t) where T : IPropA, IPropB 
    {
        MessageBox.Show(t.PropA);
        MessageBox.Show(t.PropB);
    }
}

基底クラスとインターフェイスから継承された引数と同じです。

于 2009-03-06T11:49:20.110 に答える
11
  1. まだコメントすることはできませんが、Visual Studio 2008 は既定でプロパティを自動的にステップ オーバーするため、その場合は DebuggerStepThrough 属性は不要になることに注意してください。

  2. また、パラメーターのないラムダを宣言する方法を示している人に気づいていません (Action<> の実装に役立ちます)。

    () => DoSomething(x);

クロージャーについても読む必要があります。私はクロージャーを適切に説明できるほど頭が良くありません。しかし、基本的には、ラムダを作成した後に「スコープ外」になっても、そのコード行の x が引き続き機能するように、コンパイラが巧妙なことを行うことを意味します。

  1. 最近、ラムダ パラメータを無視するふりをできることも発見しました。

    (e, _) => DoSomething(e)

本当に無視しているわけではなく、 _ が有効な識別子であることだけです。したがって、そのような両方のパラメーターを無視することはできませんが、そのパラメーター (通常は である EventArgs) を気にしないことを示すのは、一種の巧妙な方法だと思います.Empty

于 2008-09-16T13:56:08.140 に答える
10

TrueForAllメソッドList<T>

List<int> s = new List<int> { 6, 1, 2 };

bool a = s.TrueForAll(p => p > 0);
于 2008-12-23T12:27:07.580 に答える
10

多くの人が知らないことの1つは、C#で導入されたプリプロセッサディレクティブの一部です。#error This is an error.コンパイラエラーを生成するために使用できます#warning This is a warning.

私は通常、トップダウンのアプローチで「やること」リストとして開発しているときにこれらを使用します。私が#error Implement this function、または#warning Eventually implement this corner caseリマインダーとして。

于 2009-05-08T15:35:04.417 に答える
10

これがまだ言及されているかどうかはわかりませんが、ThreadStatic 属性は非常に便利なものです。これにより、静的フィールドが現在のスレッドに対してのみ静的になります。

[ThreadStatic]
private static int _ThreadStaticInteger;

アプリケーション全体で 1 回しか実行されないため、イニシャライザを含める必要はありません。フィールドを null 可能にして、使用する前に値が null かどうかを確認することをお勧めします。

もう 1 つ、ASP.NET アプリケーションのスレッドは再利用されるため、値を変更すると別のページ要求に使用される可能性があります。

それでも、私はこれがいくつかの場面で役立つことを発見しました. たとえば、次のようなカスタム トランザクション クラスを作成する場合:

using (DbTransaction tran = new DbTransaction())
{
    DoQuery("...");
    DoQuery("...");    
}

DbTransaction コンストラクターは ThreadStatic フィールドを自身に設定し、dispose メソッドで null にリセットします。DoQuery は静的フィールドをチェックし、!= null の場合は現在のトランザクションを使用します。そうでない場合は、デフォルトで別のものになります。トランザクションを各メソッドに渡す必要がなくなり、トランザクション内でトランザクションで使用することを意図していなかった他のメソッドを簡単にラップできます...

たった1回の使用:)

于 2009-06-19T13:08:28.730 に答える
10

ネストされたクラスは、外部クラスのプライベート メンバーにアクセスできます。

public class Outer
{
    private int Value { get; set; }

    public class Inner
    {
        protected void ModifyOuterMember(Outer outer, int value)
        {
            outer.Value = value;
        }
    }
}

また、上記の機能とともに、以下に示すように、ネストされたクラスを最上位クラスであるかのように継承することもできます。

public class Cheater : Outer.Inner
{
    protected void MakeValue5(Outer outer)
    {
        ModifyOuterMember(outer, 5);
    }
}

これらの機能は、ある程度隠しクラスを介して特定のメンバーへのアクセスを提供する限り、いくつかの興味深い可能性を可能にします。

于 2009-09-09T11:14:47.410 に答える
10

Or代入演算子は非常に優れています。これを書くことができます:

x |= y

これの代わりに:

x = x | y

xこれは、 で始まる変数またはプロパティ (例)が必要であるが、他の値が である場合にのみ、false他のブール変数/プロパティの値に変更したい場合に、しばしば実用的です。true

于 2009-06-30T08:55:57.547 に答える
10

以下を使用して、丸めスキームを変更できます。

var value = -0.5;
var value2 = 0.5;
var value3 = 1.4;

Console.WriteLine( Math.Round(value, MidpointRounding.AwayFromZero) ); //out: -1
Console.WriteLine(Math.Round(value2, MidpointRounding.AwayFromZero)); //out: 1
Console.WriteLine(Math.Round(value3, MidpointRounding.ToEven)); //out: 1
于 2010-03-27T23:38:47.077 に答える
10

基本クラスのコンストラクターを呼び出すには、 base() をコンストラクターとインラインで配置します。
基本クラス メソッドを呼び出すには、派生クラス メソッド内に base.MethodName() を配置するだけです。

class ClassA 
{
  public ClassA(int a)
  {
    //Do something
  }

  public void Method1()
  {
     //Do Something
  }
}

class ClassB : ClassA
{
  public ClassB(int a) : base(a) // calling the base class constructor
  {
    //Do something
  }

  public void Method2()
  {
    base.Method1();               // calling the base class method
  }
}

もちろん、単に言うだけで基底クラスのメソッドを呼び出すことができますbase.MethodName()

于 2008-12-13T21:53:01.053 に答える
9

列挙型の操作。

文字列を列挙型に変換します。

enum MyEnum
{
    FirstValue,
    SecondValue,
    ThirdValue
}

string enumValueString = "FirstValue";
MyEnum val = (MyEnum)Enum.Parse(typeof(MyEnum), enumValueString, true)
  • これを使用して、ASP.NETアプリケーションのCacheItemPriorityの値をデータベースの設定テーブルからロードし、アプリケーションを停止せずに(他の設定とともに)キャッシュを動的に制御できるようにします。

enum型の変数を比較する場合、intにキャストする必要はありません。

MyEnum val = MyEnum.SecondValue;
if (val < MyEnum.ThirdValue)
{
    // Do something
}
于 2009-04-02T10:35:23.747 に答える
9

私は関数の暗黙のジェネリックパラメーターをとても楽しんでいます。たとえば、次の場合:

public void DoStuff<T>(T value);

このように呼び出す代わりに:

DoStuff<int>(5);

あなたはできる:

DoStuff(5);

そして、パラメータの型からジェネリック型を計算します。

  • リフレクションを介してメソッドを呼び出している場合、これは機能しません。
  • 私はMonoでいくつかの奇妙な問題を抱えていたことを覚えています。
于 2009-04-02T16:30:33.247 に答える
9

デバッグ モードとリリース モードで異なる動作が必要な場合は、プリプロセッサ ディレクティブが便利です。

http://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx

于 2008-08-19T16:07:50.390 に答える
9

IEnumerableリストのSelectManyリストを単一のリストにフラット化します。Ordersのリストがあり、それぞれOrderがその順序で のリストを持っているとしましょうLineItems

LineItems累計販売数が知りたい...

int totalItems = Orders.Select(o => o.LineItems).SelectMany(i => i).Sum();
于 2008-11-24T12:51:58.030 に答える
9
System.Diagnostics.Debug.Assert (false);

ポップアップをトリガーし、実行中に実行中の .NET プロセスにデバッガーをアタッチできるようにします。何らかの理由で ASP.NET アプリケーションを直接デバッグできない場合に非常に便利です。

于 2008-09-23T14:36:02.750 に答える
9

LINQ でIEnumerable<T>が空かどうかをテストするには、次を使用します。

IEnumerable <T>.Any();

  • 最初は (IEnumerable <T>.Count() != 0) を使用していました...
    • これにより、IEnumerable 内のすべての項目が不必要<T>に列挙されます。
  • これを改善するために、私は (IEnumerable <T>.FirstOrDefault() == null)... を使い続けました。
    • どちらがいい...
  • しかし、IEnumerable <T>.Any() は最も簡潔で、最高のパフォーマンスを発揮します。
于 2010-03-01T22:37:19.970 に答える
9

ストリングインターン。これは、このディスカッションでまだ取り上げられていないものです。少しわかりにくいですが、特定の状況では便利です。

CLR は、リテラル文字列 (およびプログラムによってインターンされた文字列) への参照のテーブルを保持します。コード内の複数の場所で同じ文字列を使用すると、テーブルに 1 回格納されます。これにより、文字列の割り当てに必要なメモリ量を軽減できます。

String.IsInterned(string)を使用して文字列がインターンされているかどうかをテストでき、 String.Intern( string )を使用して文字列をインターンできます。

注: CLR は、アプリケーションまたは AppDomain の終了後にインターンされた文字列への参照を保持できます。詳細については、MSDN のドキュメントを参照してください。

于 2008-10-01T11:51:29.697 に答える
8

誰もが演算子のオーバーロードに精通していると確信していますが、そうでない人もいるかもしれません。

class myClass
{
    private string myClassValue = "";

    public myClass(string myString)
    {
        myClassValue = myString;
    }

    public override string ToString()
    {
        return myClassValue;
    }

    public static myClass operator <<(myClass mc, int shiftLen)
    {
        string newString = "";
        for (int i = shiftLen; i < mc.myClassValue.Length; i++)
            newString += mc.myClassValue[i].ToString();
        mc.myClassValue = newString.ToString();
        return mc;
    }

    public static myClass operator >>(myClass mc, int shiftLen)
    {
        char[] newString = new char[shiftLen + mc.myClassValue.Length];

        for (int i = shiftLen; i < mc.myClassValue.Length; i++)
            newString[i] += mc.myClassValue[i - shiftLen];

        mc.myClassValue = new string(newString);
        return mc;
    }

    public static myClass operator +(myClass mc, string args)
    {
        if (args.Trim().Length > 1)
            mc.myClassValue += args;
        return mc;
    }

    public static myClass operator -(myClass mc, string args)
    {
        if (args.Trim().Length > 1)
        {
            Regex rgx = new Regex(args);
            mc.myClassValue = rgx.Replace(mc.myClassValue, "");
        }
        return mc;
    }
}

<<と>>を使用して文字列を左右にシフトしたり、-=を使用して正規表現パターンに従う文字列のセットを削除したりできるのはかなりクールだと思います。

myClass tmpClass = new myClass("  HelloWorld123");
tmpClass -= @"World";
tmpClass <<= 2;
Console.WriteLine(tmpClass);
于 2008-08-24T07:52:19.547 に答える
8

C#3.5で辞書を初期化する式:

new Dictionary<string, Int64>() {{"Testing", 123}, {"Test", 125}};

于 2009-08-07T00:13:41.060 に答える
8

LINQ を使用すると、パラメーターに基づいて新しい関数を作成できます。非常に頻繁に実行される小さな関数がある場合、これは非常に便利ですが、パラメーターの計算には時間がかかります。

    public Func<int> RandomGenerator
    {
        get
        {
            var r = new Random();
            return () => { return r.Next(); };
        }
    }

    void SomeFunction()
    {
        var result1 = RandomGenerator();

        var x = RandomGenerator;
        var result2 = x();
    }
于 2010-03-20T18:00:45.117 に答える
8

ディクショナリ初期化子は、一部のデータをハードコーディングする必要がある簡単なハックや単体テストに常に役立ちます。

var dict = new Dictionary<int, string> { { 10, "Hello" }, { 20, "World" } };
于 2009-12-07T08:26:16.287 に答える
8

C# 固有のものではありませんが、私は 3 項演算中毒者です。

それ以外の

if (boolean Condition)
{
    //Do Function
}
else
{
    //Do something else
}

あなたは簡潔を使うことができます

booleanCondtion ? true operation : false operation;

例えば

それ以外の

int value = param;
if (doubleValue)
{
    value *= 2;
}
else
{
    value *= 3;
}

入力できます

int value = param * (tripleValue ? 3 : 2);

簡潔なコードを書くのに役立ちますが、いまいましいものを入れ子にするのは厄介であり、それらは悪に使用される可能性がありますが、それでも私は小さな吸盤が大好きです

于 2008-09-08T22:49:47.673 に答える
8

このような安っぽいことをする代わりに:

Console.WriteLine("{0} item(s) found.", count);

次のインライン トリックを使用します。

Console.WriteLine("{0} item{1} found.", count, count==1 ? "" : "s");

これにより、アイテムが 1 つある場合は「item」、1 つより多い (または少ない) 場合は「items」が表示されます。

于 2009-05-04T19:57:08.820 に答える
8

ひもでスイッチできる!

switch(name)
{
  case "Dave":
    return true;
  case "Bob":
    return false;
  default:
    throw new ApplicationException();
}

とても便利な!一連の if-else ステートメントよりもはるかにクリーン

于 2008-10-13T22:32:10.360 に答える
8

C# では、インターフェイス宣言自体にプロパティ セッターがない場合でも、読み取り専用インターフェイス プロパティを実装する具象型にプロパティ セッター メソッドを追加できます。例えば:

public interface IReadOnlyFoo
{
   object SomeReadOnlyProperty { get; }
}

具体的なクラスは次のようになります。

internal class Foo : IReadOnlyFoo
{
   public object SomeReadOnlyProperty { get; internal set; }
}

これの興味深い点は、Foo クラスを IReadOnlyFoo インターフェイスにキャストすると不変になることです。

// Create a Foo instance
Foo foo = new Foo();

// This statement is legal
foo.SomeReadOnlyProperty = 12345;

// Make Foo read only
IReadOnlyFoo readOnlyFoo = foo;

// This statement won't compile
readOnlyFoo.SomeReadOnlyProperty = 54321;
于 2009-11-05T00:10:43.080 に答える
7

C#4.0の動的キーワード

メソッド呼び出しを実行時にのみ解決する場合は、動的キーワードを使用できます。

dynamic invoker=new DynamicInvoker();
dynamic result1=invoker.MyMethod1();
dynamic result2=invoker.MyMethod2();

ここでは、動的呼び出し元を実装しています。

public class DynamicInvoker : IDynamicObject
    {
        public MetaObject GetMetaObject
              (System.Linq.Expressions.Expression parameter)
        {
            return new DynamicReaderDispatch (parameter);
        }
    }

    public class DynamicDispatcher : MetaObject
    {
        public DynamicDispatcher (Expression parameter) 
                   : base(parameter, Restrictions.Empty){ }

        public override MetaObject Call(CallAction action, MetaObject[] args)
        {
            //You'll get MyMethod1 and MyMethod2 here (and what ever you call)
            Console.WriteLine("Logic to invoke Method '{0}'", action.Name);
            return this; //Return a meta object
        }
    }
于 2008-12-15T15:03:09.210 に答える
7

非ジェネリッククラスにジェネリックメソッドを含めることができます。

于 2009-01-24T05:22:17.283 に答える
7

LINQを使用して、反復と条件を取得するために使用されたコレクションでインライン作業を実行する機能は、非常に価値があります。すべてのLINQ拡張メソッドが、コードをはるかにコンパクトで保守しやすくするのにどのように役立つかを学ぶ価値があります。

于 2009-08-21T11:30:38.153 に答える
7
HttpContext.Current.Server.Execute 

HTMLをAJAXコールバックの文字列にレンダリングするのに最適です。HTML文字列スニペットをつなぎ合わせる代わりに、これをコンポーネントで使用できます。実質的に混乱することなく、ページの肥大化を数百KB削減することができました。私はそれをこのように使用しました:

Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl(@"MyComponent.ascx");
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
于 2009-06-22T05:42:31.580 に答える
7

私は「ProASP.NETMVCFramework」(APress)という本を読んでいて、著者が私にとって異質な辞書オブジェクトを使って何かをしているのを観察しました。

彼は、Add()メソッドを使用せずに新しいキー/値ペアを追加しました。次に、そのキーがすでに存在するかどうかを確認せずに、同じキー/値のペアを上書きしました。例えば:

Dictionary<string, int> nameAgeDict = new Dictionary<string, int>();
nameAgeDict["Joe"] = 34;      // no error. will just auto-add key/value
nameAgeDict["Joe"] = 41;      // no error. key/value just get overwritten
nameAgeDict.Add("Joe", 30);   // ERROR! key already exists

辞書にすでにキーがあるかどうかを確認する必要がなく、それぞれのキーと値のペアを追加したい(必要に応じて既存のキーと値のペアを上書きする)場合が多くあります。この発見の前に、キーを追加する前に、キーがすでに存在するかどうかを常に確認する必要があります。

于 2010-05-14T18:46:21.680 に答える
7

「prop」と入力してから [TAB] を 2 回押すと、プロパティに役立つコードが生成され、入力が高速化されます。

これが VS 2005 で機能することは知っていますが (使用しています)、以前のバージョンではわかりません。

于 2008-08-20T19:17:16.330 に答える
7

配列要素の型を指定しない配列の初期化:

var pets = new[] { "Cat", "Dog", "Bird" };
于 2009-05-19T15:52:52.263 に答える
7

誰かがその追加について言及しているとは思いませんか?値型名の後に null 可能にします。

できるよ:

DateTime? date = null;

DateTime は構造体です。

于 2009-08-07T06:37:19.330 に答える
7

これは C# 固有の型ではありませんが、ISurrogateSelector および ISerializationSurrogate インターフェイスを見つけました --

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.isurrogateselector.aspx

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.isurrogateselector.aspx

これらを BinaryFormatter と組み合わせて使用​​すると、サロゲート クラスの実装を介してシリアル化できないオブジェクトをシリアル化できます。サロゲート パターンは、特にシリアル化の問題を扱う場合に、コンピューター サイエンスでよく理解されています。この実装は、コンストラクターのパラメーターとして BinaryFormatter に隠されているだけだと思いますが、それは残念です。

まだ-非常に隠されています。:)

于 2008-11-25T22:53:40.513 に答える
7

Eric Lippert による4 つのスイッチの奇妙さ

于 2009-08-14T12:13:18.657 に答える
7

好き

#if DEBUG
           //Code run in debugging mode

#else
           //Code run in release mode

#endif
于 2010-04-05T12:25:40.910 に答える
7

ラムダを使用するときに機能的な「ワイルドカード」引数 (Haskell の「_」など) をエミュレートするクールなトリック:

(_, b, __) => b.DoStuff();  // only interested in b here
于 2009-01-31T04:50:20.090 に答える
7

duncansmart の回答に加えて、拡張メソッドも Framework 2.0 で使用できます。System.Runtime.CompilerServices 名前空間の下にクラスを追加するExtensionAttributeだけで、拡張メソッドを使用できます (もちろん C# 3.0 のみ)。

namespace System.Runtime.CompilerServices
{
    public class ExtensionAttribute : Attribute
    { 
    }
}
于 2008-08-14T11:07:01.447 に答える
7

明示的なインターフェイス メンバーの実装。インターフェイス メンバーは実装されますが、インスタンスがインターフェイス型にキャストされない限り非表示になります。

于 2008-11-18T15:56:03.277 に答える
7

通常のメソッドであるかのように、拡張メソッドからデリゲートを作成して、thisパラメーターをカリー化できます。例えば、

static class FunnyExtension {
    public static string Double(this string str) { return str + str; }
    public static int Double(this int num) { return num + num; }
}


Func<string> aaMaker = "a".Double;
Func<string, string> doubler = FunnyExtension.Double;

Console.WriteLine(aaMaker());       //Prints "aa"
Console.WriteLine(doubler("b"));    //Prints "bb"

これは、値型を拡張する拡張メソッドでは機能しないことに注意してください。この質問を参照してください。

于 2009-06-19T01:59:31.780 に答える
7

高度なデバッグ

画面

前述の属性 DebuggerDisplay および DebuggerBrowsable は、要素の可視性と表示されるテキスト値を制御します。ToString() をオーバーライドするだけで、デバッガーはそのメソッドの出力を使用します。

より複雑な出力が必要な場合は、Debugger Visualizerを使用/作成できます。いくつかの例をここで入手できます。

ストライクの息子

Microsoft は、 SOSと呼ばれるデバッガ拡張機能を提供しています。これは非常に強力な (しばしば混乱を招く) 拡張機能であり、「リーク」を診断するための優れた方法であり、より正確には、不要になったオブジェクトへの参照を診断する優れた方法です。

フレームワーク ソースのシンボル サーバー

これらの手順に従うと、フレームワークの一部のソースをステップ実行できます。

2010年の変化

Visual Studio 2010 には、いくつかの拡張機能と新機能があります。

  • 並列タスクのデバッグ
  • 並列スタックを使用すると、複数のスレッドの呼び出しスタックを同時に表示できます。
  • ヒストリカル デバッグを使用すると、イベントと非ローカル変数を過去にさかのぼって確認できます (事前にコレクションを有効にしている場合)。デバッグ方法が大きく変わる可能性があります。
于 2009-06-14T17:31:46.930 に答える
7

Object.ReferenceEquals メソッド

指定された Object インスタンスが同じインスタンスかどうかを判断します。

パラメーター:

  • objA: System.Object - 比較する最初のオブジェクト。
  • objB: System.Object - 比較する 2 番目のオブジェクト。

例:

 object o = null;
 object p = null;
 object q = new Object();

 Console.WriteLine(Object.ReferenceEquals(o, p));
 p = q;
 Console.WriteLine(Object.ReferenceEquals(p, q));
 Console.WriteLine(Object.ReferenceEquals(o, p));

"==" と ".Equals" との違い:

基本的に、オブジェクト A の Equals() テストは、オブジェクト B と同じ内容です。

メソッド System.Object.ReferenceEquals() は常に参照を比較します。クラスは等価演算子 (下記) に独自の動作を提供できますが、System.Object への参照を介して演算子が呼び出された場合、その再定義された演算子は呼び出されません。

文字列の場合、文字列の内容を比較するために == と Equals の両方がオーバーライドされているため、実際には違いはありません。

別の質問に対するこの回答も参照してください(「無限再帰なしで '==' 演算子のオーバーロードで null をチェックするにはどうすればよいですか?」)。

于 2008-10-25T09:53:31.090 に答える
7

コンポーネントを表示するときに表示するプロパティ デザイン ビューでのプロパティ:

private double _Zoom = 1;

[Category("View")]
[Description("The Current Zoom Level")]
public double Zoom
{
get { return _Zoom;}
set { _Zoom = value;}
}

コンポーネント ライブラリの他のユーザーにとって、作業が非常に簡単になります。

于 2009-06-03T15:03:23.143 に答える
7
[field: NonSerialized]
public event EventHandler Event;

この方法では、イベント リスナーはシリアル化されません。

NonSerializedAttribute はフィールドにしか適用できないため、[NonSerialized] だけでは機能しません。

于 2009-07-22T01:42:45.620 に答える
7

組み込み (2.0) の MethodInvoker デリゲートは、インライン コードを Invoke/BeginInvoke する場合に便利です。これにより、実際のデリゲートと個別のメソッドを作成する必要がなくなります。

    void FileMessageEvent(object sender, MessageEventArgs e)
    {

        if (this.InvokeRequired == true)
        {
            this.BeginInvoke((MethodInvoker)delegate { 
                     lblMessage.Text=e.Message; 
                     Application.DoEvents(); 
                 }
            ); 

        }
    }

エラーを解決します:「デリゲート型ではないため、匿名メソッドを型 'System.Delegate' に変換できません」。

于 2009-05-14T09:05:37.560 に答える
7

これは私が最近発見した便利なものです:

Microsoft.VisualBasic.Logging.FileLogTraceListener

MSDN リンク

これは、自動ログ ファイル ロール オーバーなど、以前はカスタム ロギング フレームワークを使用していた多くの機能を備えた TraceListener 実装です。良い点は、これが .NET のコア部分であり、Trace フレームワークと統合されているため、簡単に取得してすぐに使用できることです。

これは、Microsoft.VisualBasic アセンブリに含まれているため「非表示」になっていますが、C# からも使用できます。

于 2009-04-01T21:50:41.820 に答える
7

これが言及されているかどうかはわかりません(11ページ!!)

しかし、OptionalFieldシリアル化されるクラス/オブジェクトをバージョン管理する場合、クラスの属性は驚くべきものです。

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

于 2010-07-06T19:46:43.967 に答える
6

それらを:と組み合わせるまで、クラス内のいくつかの関数Convert(Convert.ToDouble(int)、Convert.ToInt(double)など)が何を使用しているかを理解できませんでした。Array.ConvertAll

int[] someArrayYouHaveAsInt;
double[] copyOfArrayAsDouble = Array.ConvertAll<int, double>(
                                someArrayYouHaveAsInt,
                                new Converter<int,double>(Convert.ToDouble));

これにより、インラインデリゲート/クロージャの定義から生じるリソース割り当ての問題が回避されます(そして少し読みやすくなります)。

int[] someArrayYouHaveAsInt;
double[] copyOfArrayAsDouble = Array.ConvertAll<int, double>(
                                someArrayYouHaveAsInt,
                                new Converter<int,double>(
                                  delegate(int i) { return (double)i; }
                                ));
于 2009-05-19T11:00:33.940 に答える
6

オープンジェネリックは、特に制御の反転を使用する場合のもう1つの便利な機能です。

container.RegisterType(typeof(IRepository<>), typeof(NHibernateRepository<>));
于 2009-09-27T19:04:44.140 に答える
6

リテラルは、そのタイプの変数として使用できます。例えば。

Console.WriteLine(5.ToString());
Console.WriteLine(5M.GetType());   // Returns "System.Decimal"
Console.WriteLine("This is a string!!!".Replace("!!", "!"));

ちょっとした雑学...

人々が言及していないことはかなりありますが、それらは主に安全でない構造と関係があります。ただし、「通常の」コードで使用できるものは次のとおりです。

チェックされた/チェックされていないキーワード:

public static int UncheckedAddition(int a, int b)
{
    unchecked { return a + b; }
}

public static int CheckedAddition(int a, int b)
{
    checked { return a + b; } // or "return checked(a + b)";
}

public static void Main() 
{
    Console.WriteLine("Unchecked: " + UncheckedAddition(Int32.MaxValue, + 1));  // "Wraps around"
    Console.WriteLine("Checked: " + CheckedAddition(Int32.MaxValue, + 1));  // Throws an Overflow exception
    Console.ReadLine();
}
于 2008-09-19T15:59:09.043 に答える
6

C#のポインター。

これらは、インプレースの文字列操作を行うために使用できます。これは安全でない機能であるため、安全でないコードの領域をマークするためにunsafeキーワードが使用されます。また、fixedキーワードを使用して、ポイントされたメモリが固定されており、GCで移動できないことを示す方法にも注意してください。これは、ポインタがメモリアドレスを指すために不可欠であり、GCはメモリを別のアドレスに移動できます。そうしないと、ポインタが無効になります。

    string str = "some string";
    Console.WriteLine(str);
    unsafe
    {
        fixed(char *s = str)
        {
            char *c = s;
            while(*c != '\0')
            {
                *c = Char.ToUpper(*c++);                    
            }
        }
    }
    Console.WriteLine(str);

私はこれを行うことはありませんが、この機能を示すためにこの質問をするためだけに行います。

于 2009-07-13T11:05:00.177 に答える
6

匿名メソッドからローカル変数にアクセスすると、そのコードを別のメソッドに分解することなく、新しい制御フロー ロジックでほぼすべてのコードをラップできます。endOfLineCharメソッドの外部で宣言されたローカル変数は、次の例のローカル変数のように、メソッド内で使用できます。

http://aaronls.wordpress.com/2010/02/02/retrying-on-exception-conditionally/

于 2010-07-06T19:52:37.000 に答える
6

これは、 T が public parameterless constructor を持たなければならないことを意味します:

 class MyClass<T> where T : new()
 {

 }
于 2010-05-02T13:17:49.230 に答える
6

新しい修飾子

C# での "new" 修飾子の使用は完全に隠されているわけではありませんが、あまり見られません。new 修飾子は、基本クラスのメンバーを「非表示」にする必要があり、常にオーバーライドする必要がない場合に便利です。これは、派生クラスを基本クラスとしてキャストすると、「非表示」メソッドが表示され、派生クラスの同じメソッドの代わりに呼び出されることを意味します。

コードで見るのは簡単です:

public class BaseFoo
{
    virtual public void DoSomething()
    {
        Console.WriteLine("Foo");
    }
}

public class DerivedFoo : BaseFoo
{
    public new void DoSomething()
    {
        Console.WriteLine("Bar");
    }
}

public class DerivedBar : BaseFoo
{
    public override void DoSomething()
    {
        Console.WriteLine("FooBar");
    }
}

class Program
{
    static void Main(string[] args)
    {
        BaseFoo derivedBarAsBaseFoo = new DerivedBar();
        BaseFoo derivedFooAsBaseFoo = new DerivedFoo();

        DerivedFoo derivedFoo = new DerivedFoo();

        derivedFooAsBaseFoo.DoSomething(); //Prints "Foo" when you might expect "Bar"
        derivedBarAsBaseFoo.DoSomething(); //Prints "FooBar"

        derivedFoo.DoSomething(); //Prints "Bar"
    }
}

[編集者: ダジャレで追加ポイントを獲得できますか? 申し訳ありませんが、仕方がありませんでした。]

于 2008-09-17T20:28:37.203 に答える
6

Visual Studio での条件付きブレーク機能の使用は非常に便利です。たとえば、めったに見られないような値に値を設定して、そこからさらにコードを調べることができる方法が気に入っています。

于 2010-01-10T01:27:07.047 に答える
6

メソッド グループはあまり知られていません。

与えられた:

Func<Func<int,int>,int,int> myFunc1 = (i, j) => i(j);
Func<int, int> myFunc2 = i => i + 2;

あなたはこれを行うことができます:

var x = myFunc1(myFunc2, 1);

これの代わりに:

var x = myFunc1(z => myFunc2(z), 1);
于 2009-02-27T00:45:20.403 に答える
6

Yield キーワードは、多くのパワーがある場合に見過ごされがちです。私は少し前にそれについてブログを書き、利点 (処理の違い) について説明しました。

C# での Yield の使用

于 2009-06-18T03:44:34.440 に答える
6

不変性、共変性、反変性の意味を学んだところで、.NET 4.0 に含まれるinおよびoutジェネリック修飾子を発見しました。それらはほとんどのプログラマーが知らないほど曖昧に見えます。

Visual Studio Magazine には、これらのキーワードとその使用方法について説明した記事があります。

于 2009-05-26T21:23:24.767 に答える
6

私はこの質問にとても遅れていますが、カバーされていないと思われるいくつかを追加したいと思いました. これらは C# 固有のものではありませんが、C# 開発者にとって言及する価値があると思います。

AmbientValue 属性

これは に似てDefaultValueAttributeいますが、プロパティのデフォルトの値を提供する代わりに、プロパティがその値を別の場所から要求するかどうかを決定するために使用する値を提供します。たとえば、WinForms の多くのコントロールでは、親コントロールから色を取得できるように、プロパティForeColorBackColorプロパティにAmbientValueofがあります。Color.Empty

分離ストレージ設定

これはSilverlightのものです。フレームワークには、アプリケーションごととサイトごとの両方のレベルで設定の永続性を提供するために、このシールされたクラスが手軽に含まれています。

拡張メソッドとの相互作用にフラグを立てる

拡張メソッドを使用すると、フラグ列挙の使用がはるかに読みやすくなります。

    public static bool Contains(
          this MyEnumType enumValue,
          MyEnumType flagValue)
    {
        return ((enumValue & flagValue) == flagValue);
    }

    public static bool ContainsAny(
          this MyEnumType enumValue,
          MyEnumType flagValue)
    {
        return ((enumValue & flagValue) > 0);
    }

これにより、フラグ値のチェックが適切に行われ、読み書きが容易になります。もちろん、ジェネリックを使用して T を enum にすることができればもっといいのですが、それは許可されていません。おそらくdynamicこれを簡単にするでしょう。

于 2009-05-08T18:21:05.907 に答える
6

これは C# 固有の機能ではありませんが、非常に便利なアドオンです。これは、リソース リファクタリング ツールと呼ばれます。リテラル文字列を右クリックして、リソース ファイルに抽出できます。コードを検索し、一致する他のリテラル文字列を見つけて、Resx ファイルの同じリソースに置き換えます。

http://www.codeplex.com/ResourceRefactoring

于 2008-12-16T22:16:59.270 に答える
6

int.TryParse() または Convert.ToInt32() を使用する代わりに、解析できない場合に null を返す静的な整数解析関数を使用するのが好きです。次に、使用できますか?? 三項演算子を組み合わせて、宣言と初期化がすべて 1 行でわかりやすく行われるようにします。

public static class Parser {
    public static int? ParseInt(string s) {
        int result;
        bool parsed = int.TryParse(s, out result);
        if (parsed) return result;
        else return null;
    }
    // ...
}

これは、代入の左側の重複を避けるのにも適していますが、次の例のデータベース呼び出しなど、代入の右側で長い呼び出しが重複するのを避けるのにも適しています。醜いif-thenツリー(私がよく遭遇する)の代わりに:

int x = 0;
YourDatabaseResultSet data = new YourDatabaseResultSet();
if (cond1)
    if (int.TryParse(x_input, x)){
        data = YourDatabaseAccessMethod("my_proc_name", 2, x);
    }
    else{
        x = -1;
        // do something to report "Can't Parse"    
    }
}
else {
    x = y;
    data = YourDatabaseAccessMethod("my_proc_name", 
       new SqlParameter("@param1", 2),
       new SqlParameter("@param2", x));
}

できるよ:

int x = cond1 ? (Parser.ParseInt(x_input) ?? -1) : y;
if (x >= 0)  data = YourDatabaseAccessMethod("my_proc_name", 
    new SqlParameter("@param1", 2),
    new SqlParameter("@param2", x));

はるかにクリーンで理解しやすい

于 2008-10-06T21:16:08.717 に答える
6

@ブラッド・バーカー

Nullable 型を使用する必要がある場合は、疑問符表記ではなく Nullable<.T> を使用する方がよいと思います。魔法が起こっていることが目障りなほど明らかです。ただし、なぜ Nullable<.bool> を使用したいのかはわかりません。:-)

Krzysztof Cwalina (Framwork Design Guidlines の作成者の 1 人) は、ここに良い投稿をしています: http://blogs.msdn.com/kcwalina/archive/2008/07/16/Nullable.aspx

そして、Mike Hadlow はNullability Voodooに関する素敵な投稿をしています。

于 2008-08-12T18:40:45.340 に答える
6

順不同:

Lists<>
Mutex

Framework 3.5 の新しいプロパティ定義のショートカット。

于 2008-08-12T19:40:28.030 に答える
6

@dp AnonCastについて考え、少し試してみることにしました。これが私が思いついたもので、一部の人にとって役立つかもしれません:

// using the concepts of dp's AnonCast
static Func<T> TypeCurry<T>(Func<object> f, T type)
{
    return () => (T)f();
}

そして、これがどのように使用されるかは次のとおりです。

static void Main(string[] args)
{

    var getRandomObjectX = TypeCurry(GetRandomObject,
        new { Name = default(string), Badges = default(int) });

    do {

        var obj = getRandomObjectX();

        Console.WriteLine("Name : {0} Badges : {1}",
            obj.Name,
            obj.Badges);

    } while (Console.ReadKey().Key != ConsoleKey.Escape);

}

static Random r = new Random();
static object GetRandomObject()
{
    return new {
        Name = Guid.NewGuid().ToString().Substring(0, 4),
        Badges = r.Next(0, 100)
    };
}
于 2008-08-28T20:07:41.743 に答える
6

これを AutoDebug と呼んでいるのは、プロジェクトのユーザー設定としても保存できる bool 値に基づいて、必要な場所とタイミングでデバッグを開始できるためです。

例:

//Place at top of your code
public UseAutoDebug = true;


//Place anywhere in your code including catch areas in try/catch blocks
Debug.Assert(!this.UseAutoDebug);

上記を try/catch ブロックまたはコードの他の領域に配置し、UseAutoDebug を true または false に設定して、テストが必要なときにいつでもデバッグにドロップします。

このコードをそのままにして、テスト時にこの機能のオンとオフを切り替えることができます。また、プロジェクト設定として保存し、展開後に手動で変更して、必要に応じてユーザーから追加のバグ情報を取得することもできます。

この Visual Studio C# プロジェクト テンプレートで、この手法を使用した機能的で実用的な例をここで確認できます。ここでは、頻繁に使用されています。

http://code.msdn.microsoft.com/SEHE

于 2008-12-30T01:40:37.583 に答える
6

特に、null 許容の DateTime が気に入っています。したがって、日付が指定されている場合と日付が指定されていない場合がある場合は、これを使用するのが最善であり、IMHO を使用する方が理解しやすいと思いDateTime.MinValueます...

DateTime? myDate = null;

if (myDate.HasValue)
{
    //doSomething
}
else
{
    //soSomethingElse
}
于 2009-07-22T08:39:34.373 に答える
6

列挙型のデータ型を定義できます。

enum EnumName : [byte, char, int16, int32, int64, uint16, uint32, uint64]
{
    A = 1,
    B = 2
}
于 2009-06-07T07:26:09.073 に答える
6

.NET フレームワークの開発に関する本を読んでいます。bool を使用してオンまたはオフにするのではなく、ENums を使用することをお勧めします。

ENums を使用すると、新しい機能を関数に追加するためにコードを書き直す必要なく、ある程度の拡張性を得ることができます。

于 2008-08-25T15:09:18.617 に答える
6

境界をチェックするための Math.Max と Min: 私はこれを多くのコードで見てきました:

if (x < lowerBoundary) 
{
   x = lowerBoundary;
}

これは小さく、きれいで、読みやすいと思います:

x = Math.Max(x, lowerBoundary);

または、三項演算子を使用することもできます。

x = ( x < lowerBoundary) ? lowerBoundary : x;
于 2008-11-04T23:24:03.120 に答える
6

についてforeach:ダックタイピングIMOはランタイムチェックを指すため、「ダックタイピング」は使用しません。コンパイル時に (公称ではなく)構造型チェックを使用して、型に必要なメソッドがあるかどうかをチェックします。

于 2008-11-17T09:28:42.047 に答える
6

(私はこれを使用しました)フィールドをnullに設定し、中間変数なしで返します:

try
{
    return _field;
}
finally
{
    _field = null;
}
于 2008-11-18T15:52:15.843 に答える
6

外部変数の使用をシュガー コード化するために、コンパイラがどのような種類の問題を経験するかは信じられないほどです。

string output = "helo world!";
Action action = () => Console.WriteLine(output);
output = "hello!";
action();

これは実際に印刷されhello!ます。なんで?コンパイラは、デリゲートのネストされたクラスを作成し、すべての外部変数のパブリック フィールドを作成し、デリゲートへのすべての呼び出しの前に設定コードを挿入するためです :) 上記のコードは「反射」されています。

Action action;
<>c__DisplayClass1 CS$<>8__locals2;
CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.output = "helo world!";
action = new Action(CS$<>8__locals2.<Main>b__0);
CS$<>8__locals2.output = "hello!";
action();

かなりクールだと思います。

于 2009-05-17T08:41:55.380 に答える
6

この記事の 9 ページすべてを読んだ後、少し知られていない機能を指摘しなければならないと感じました...

これは .NET 1.1 にも当てはまり、gzip 圧縮されたファイルで圧縮/解凍を使用する場合、次のいずれかを行う必要がありました。

  • ICSharpCode.ZipLib をダウンロード
  • または、プロジェクトで Java ライブラリを参照し、Java の組み込みライブラリを使用して、GZip の圧縮/解凍方法を利用します。

私が知らなかった (.NET 2/3.5 でもまだ ICSharpCode.ZipLib を使用している) あまり使用されていないのは、System.IO.Compression 名前空間で、標準の BCL バージョン 2 以降に組み込まれたことでした.. . MSDN ページの「GZipStream クラス」を参照してください。

于 2010-01-09T01:48:03.140 に答える
6

ミックスインは便利な機能です。基本的に、ミックスインを使用すると、クラスではなくインターフェイスの具体的なコードを使用できます。次に、インターフェイスを一連のクラスに実装するだけで、自動的に mixin 機能が得られます。たとえば、ディープ コピーを複数のクラスに混在させるには、インターフェイスを定義します。

internal interface IPrototype<T> { }

このインターフェースに機能を追加する

internal static class Prototype
{
  public static T DeepCopy<T>(this IPrototype<T> target)
  {
    T copy;
    using (var stream = new MemoryStream())
    {
      var formatter = new BinaryFormatter();
      formatter.Serialize(stream, (T)target);
      stream.Seek(0, SeekOrigin.Begin);
      copy = (T) formatter.Deserialize(stream);
      stream.Close();
    }
    return copy;
  }
}

次に、任意のタイプのインターフェイスを実装して、ミックスインを取得します。

于 2008-11-06T21:47:46.743 に答える
5

これについて言及されていることをお詫びしますが、私はこれを頻繁に使用します。

Visual Studioのアドインは、AlexPapadimoulisによって開発されました。通常のテキストを文字列、文字列ビルダー、コメント、またはリージョンとして貼り付けるために使用されます。

http://weblogs.asp.net/alex_papadimoulis/archive/2004/05/25/Smart-Paster-1.1-Add-In---StringBuilder-and-Better-C_2300_-Handling.aspx

このプラグインでは(これが言及されているかどうかもわかりません)、文字列が文字列リテラルプレフィックスで貼り付けられていることに気付きました:

@

これらについては知っていましたが、リテラル内で二重引用符を使用して引用符をエスケープすることについては知りませんでした。

例えば

string s = "A line of text" + Environment.NewLine + "Another with a \"quote\"!!";

次のように表すことができます

string s = @"A line of text 
Another with a ""quote""!!";
于 2009-09-11T03:52:09.283 に答える
5

ゼロパラメータラムダ

()=>Console.ReadLine()
于 2009-07-27T00:43:31.763 に答える
5

EditorBrowsableAttributeが好きです。Intellisenseでメソッド/プロパティを表示するかどうかを制御できます。値は、Always、Advanced、またはNeverに設定できます。

MSDNから..。

備考

EditorBrowsableAttributeは、プロパティまたはメソッドのどちらを表示するかを示すデザイナーへのヒントです。ビジュアルデザイナーまたはテキストエディターでこのタイプを使用して、ユーザーに表示される内容を決定できます。たとえば、Visual StudioのIntelliSenseエンジンは、この属性を使用して、プロパティまたはメソッドを表示するかどうかを決定します。

Visual C#では、[ツール] | [詳細メンバーの非表示]設定で、IntelliSenseと[プロパティ]ウィンドウに詳細プロパティを表示するタイミングを制御できます。オプション| テキストエディタ| C#。対応するEditorBrowsableStateはAdvancedです。

于 2009-11-21T08:12:56.197 に答える
5

linqxmlを使用しているときに、この手法が面白いと思います。

public bool GetFooSetting(XElement ndef){
   return (bool?)ndef.Element("MyBoolSettingValue") ?? true;
}

とは対照的に:

public bool GetFooSetting(XElement ndef){
   return ndef.Element("MyBoolSettingValue") != null ? bool.Parse(ndef.Element("MyBoolSettingValue") ) : true;
}
于 2008-10-12T04:26:32.297 に答える
5

一般的なイベント ハンドラー:

public event EventHandler<MyEventArgs> MyEvent;

この方法では、常に独自のデリゲートを宣言する必要はありません。

于 2008-11-03T15:26:12.897 に答える
5

修正済み/ C# におけるポインターの力 - このトピックは大きすぎますが、簡単なことの概要を説明します。

Cでは、次のような構造をロードする機能がありました...

struct cType{
   char type[4];
   int  size;
   char name[50];
   char email[100];
}

cType myType;
fread(file, &mType, sizeof(mType));

「unsafe」メソッドで fixed キーワードを使用して、バイト配列で整列された構造を読み取ることができます。

[Layout(LayoutKind.Sequential, Pack=1)]
public unsafe class CType{
    public fixed byte type[4];
    public int size;
    public fixed byte name[50];
    public fixed byte email[100];
}

方法 1 (通常のストリームからバイト バッファーに読み込み、バイト配列を構造体の個々のバイトにマッピングする)

CType mType = new CType();
byte[] buffer = new byte[Marshal.SizeOf(CType)];
stream.Read(buffer,0,buffer.Length);
// you can map your buffer back to your struct...
fixed(CType* sp = &mType)
{
    byte* bsp = (byte*) sp;
    fixed(byte* bp = &buffer)
    {
         for(int i=0;i<buffer.Length;i++)
         {
             (*bsp) = (*bp);
             bsp++;bp++;
         }
    }
}

方法 2、Win32 User32.dll の ReadFile をマッピングしてバイトを直接読み取ることができます...

CType mType = new CType();
fixed(CType* p = &mType)
{
    User32.ReadFile(fileHandle, (byte*) p, Marshal.SizeOf(mType),0);
}
于 2009-04-23T12:57:48.963 に答える
5

中括弧付きの空のブロックは許可されています。

このようなコードを書くことができます

{
    service.DoTonsOfWork(args);
}

usingまたはを使用せずに何かを試してみたい場合に役立ちますtry... finally

//using(var scope = new TransactionScope)
{
    service.DoTonsOfWork(args);
}
于 2010-03-08T22:43:57.697 に答える
5

ラムダ メソッドと組み合わせた Action および Func デリゲート ヘルパー。これらは、可読性を向上させるためにデリゲートが必要な単純なパターンに使用します。たとえば、単純なキャッシュ パターンは、要求されたオブジェクトがキャッシュに存在するかどうかを確認することです。存在する場合: キャッシュされたオブジェクトを返します。存在しない場合は、新しいインスタンスを生成し、新しいインスタンスをキャッシュして、新しいインスタンスを返します。オブジェクトごとにこのコードを 1000 回記述するのではなく、キャッシュから保存/取得する可能性があるため、次のような単純なパターン メソッドを記述できます...

private static T CachePattern<T>(string key, Func<T> create) where T : class
{
    if (cache[key] == null)
    {
        cache.Add(key, create());
    }

    return cache[key] as T;
}

...次に、カスタム キャッシュ マネージャーで次のコードを使用して、キャッシュの取得/設定コードを大幅に簡素化できます。

public static IUser CurrentUser
{
    get
    {
        return CachePattern<IUser>("CurrentUserKey", () => repository.NewUpUser());
    }
}

単純な「日常」のコード パターンを一度記述すれば、はるかに簡単に再利用できるようになりました。デリゲート型を書きに行ったり、コールバックなどを実装する方法を考えたりする必要はありません。10 秒で書き込めるなら、私にはあまり向いていません。単純なコードパターンを切り取り/貼り付けに頼るには、それらが遅延初期化や上記の他の例であるかどうかにかかわらず...

于 2009-12-25T21:33:48.763 に答える
5

@lainMH、

null 許容ブール値は、データベースから null 許容の値を取得する場合や、値を戻す場合に役立ちます。フィールドが設定されていないことを知りたい場合があります。

于 2008-08-25T14:21:57.183 に答える
5

私はこれを見ませんでした:

for (;;);

と同じ

while (true) ;
于 2009-07-30T03:57:06.083 に答える
5

最近学んだことの 1 つは、null 許容値でメソッドを呼び出すことができるということです....

null 許容値がある場合は次のようになります。

decimal? MyValue = null;

あなたが書く必要があると思うかもしれない場所:

MyValue == null ? null : MyValue .ToString()

代わりに次のように書くことができます:

MyValue.ToString()

MyValue.HasValue と MyValue.Value を呼び出すことができることは認識していましたが、ToString() を呼び出すことができるかどうかは完全にはわかりませんでした。

于 2009-08-23T11:07:06.030 に答える
5

__arglist も

[DllImport("msvcrt40.dll")]
public static extern int printf(string format, __arglist);

static void Main(string[] args)
{
   printf("Hello %s!\n", __arglist("Bart"));
}
于 2009-12-03T00:45:50.267 に答える
5

Nullable.GetValueOrDefault ?

于 2010-04-05T11:15:10.473 に答える
5

Reflection Emit と Expression ツリーが思い浮かびます...

Jeffrey Richter の C# による CLR と Jon Skeet の CLR をお見逃しなく代替テキスト

いくつかのリソースについては、ここを参照してください。

http://www.codeproject.com/KB/trace/releasemodebreakpoint.aspx

http://www.codeproject.com/KB/dotnet/Creating_Dynamic_Types.aspx

http://www.codeproject.com/KB/cs/lambdaexpressions.aspx

于 2008-08-26T18:51:13.473 に答える
5

これはコンパイルされません:

namespace ns
{
    class Class1
    {
        Nullable<int> a;
    }
}

型または名前空間名 'Nullable' が見つかりませんでした (using ディレクティブまたはアセンブリ参照がありませんか?) <-- ' using System;'がありません

しかし

namespace ns
{
    class Class1
    {
        int? a;
    }
}

コンパイルします!(.NET 2.0)。

于 2009-09-03T03:36:51.900 に答える
5

System.Runtime.Remoting.Proxies.RealProxy

C# でのアスペクト指向プログラミングを可能にし、それを使って他の多くの凝ったことを行うこともできます。

于 2008-09-16T14:43:44.000 に答える
5

ほぼ 1 年間、厳密に型指定された DataRows に Is[ColumnName]Null() メソッドが含まれていることを知りませんでした。

例えば:

Units.UnitsDataTable dataTable = new Units.UnitsDataTable();

foreach (Units.UnitsRow row in dataTable.Rows)
{
    if (row.IsPrimaryKeyNull())
        //....

    if (row.IsForeignKeyNull())
        //....
}
于 2008-11-03T16:16:07.820 に答える
5

usingディレクティブを使用して、次のように読みやすいように一部のクラスの名前を変更するのが好きです。

// defines a descriptive name for a complexed data type
using MyDomainClassList = System.Collections.Generic.List<
  MyProjectNameSpace.MyDomainClass>;

....


MyDomainClassList myList = new MyDomainClassList();
/* instead of 
List<MyDomainClass> myList = new List<MyDomainClass>();
*/

これは、コードのメンテナンスにも非常に便利です。クラス名を変更する必要がある場合、変更する必要があるのは 1 か所だけです。もう一つの例:

using FloatValue  = float; // you only need to change it once to decimal, double...

....
FloatValue val1;
...
于 2009-07-16T05:16:29.323 に答える
4

多くの人がCのポインターについて知っていると思いますが、C#で機能するかどうかはわかりません。安全でないコンテキストでC#のポインターを使用できます。

static void Main()
{
    int i;
    unsafe
    {               
        // pointer pi has the address of variable i
        int* pi = &i; 
        // pointer ppi has the address of variable pi
        int** ppi = &pi;
        // ppi(addess of pi) -> pi(addess of i) -> i(0)
        i = 0;
        // dereference the pi, i.e. *pi is i
        Console.WriteLine("i = {0}", *pi); // output: i = 0
        // since *pi is i, equivalent to i++
        (*pi)++;
        Console.WriteLine("i = {0}", *pi); // output: i = 1
        // since *ppi is pi, one more dereference  *pi is i 
        // equivalent to i += 2
        **ppi += 2;
        Console.WriteLine("i = {0}", *pi);// output: i = 3
    }
    Console.ReadLine();
}
于 2008-09-20T01:50:13.817 に答える
4

シリアル化不可能なマーケティングイベント:

[field:NonSerializable]
public event SomeDelegate SomeEvent;
于 2009-06-22T12:29:48.727 に答える
4

私からのいくつか-あなたが望むものをそれらにしてください。

属性:

[assembly::InternalsVisibleTo("SomeAssembly")]

内部メソッド/プロパティまたはデータをアセンブリから「SomeAssembly」と呼ばれる別のアセンブリに公開できます。すべての保護された/プライベートなものは隠されたままです。


静的コンストラクター(別名「型コンストラクター」)

public MyClass
{
  public static MyClass()
  {
     // type init goes here
  }
  ......
}  

キーワードinternal。非常に多くの点でとても便利です。

于 2009-06-14T16:11:16.937 に答える
4

InternalsVisibleToAttributeは、現在のアセンブリ内でのみ通常表示されるタイプが別のアセンブリに表示されることを指定します。msdnに関する記事

于 2009-04-27T16:46:52.050 に答える
4
  • 付け ますか?タイプにnull許容にする、例:int?
  • @ "C:\dir "の代わりに"c: \ dir"
于 2010-01-07T15:57:15.387 に答える
4

式ツリーはどうですか?これらはLINQの心臓部であり、実行の延期を可能にします。

David Haydenのブログから引用:

C#3.0では、ラムダ式を使用して次のようにデリゲートを定義できます。

Func<int,int> f = x => x + 1;

このデリゲートは、アプリケーションで実行可能コードにコンパイルされ、次のように呼び出すことができます。

var three = f(2); // 2 + 1

コードは期待どおりに機能します。ここには何も派手なものはありません。

式ツリー

System.Query.Expressionを使用してデリゲートを式ツリーとして定義する場合:

Expression<Func<int,int>> expression = x => x + 1;

デリゲートは実行可能コードにコンパイルされなくなりましたが、元のデリゲートに変換およびコンパイルできるデータとしてコンパイルされました。

アプリケーションで式ツリーとして表されるデリゲートを実際に使用するには、アプリケーションでそれをコンパイルして呼び出す必要があります。

var originalDelegate = expression.Compile();

var three = originalDelegate.Invoke(2);
于 2009-07-21T21:46:11.613 に答える
4

[UnmanagedFunctionPointerAttribute(CallingConvention.CDecl)]__stdcallなしでコールバックを定義したアンマネージC++関数ライブラリとのインターフェースを試みることの喜びを学びました。

于 2008-11-03T15:42:24.097 に答える
4

私が学んだ興味深いことの 1 つは、フレームワークと C# 言語のさまざまな部分がさまざまな時期に作成されたため、矛盾が生じているということです。たとえば、フレームワーク自体が多くの FxCop ルールに違反しています。これは、フレームワークが作成された時点ですべてのルールが整っていなかったからです。

また、using ステートメントは「スコープ」を明確にするためのものであり、特にリソースを破棄するためのものではありません。lock文の後に書かれています。Eric Gunnersonはかつて、using ステートメントが最初に来れば、lock ステートメントを書く必要はなかったかもしれない (とはいえ、それは知っているかもしれませんが)、using ステートメントで十分だったかもしれないということを述べていました。

于 2008-08-24T22:10:22.963 に答える
4

#region {string}と #endregion のペアは、コードのグループ化 (アウトライン化) に非常に適しています。

#region Using statements
using System;
using System.IO;
using ....;
using ....;
#endregion

コード ブロックは、1 行の説明テキストに圧縮できます。関数内でも機能します。

于 2008-09-19T05:18:35.503 に答える
4

これの多くは、標準ですでに説明されています。専門家だけでなく初心者にとっても読みやすく、読む量は多いですが、公式の基準であり、詳細な情報が満載です。

C# を完全に理解したら、次はこれをさらに進めてCommon Language Infrastructureの基礎を理解します。C# のアーキテクチャと基盤。

私は、オブジェクトと ValueType の違いを、その固有の制限を除けば知らないプログラマーにたくさん会ってきました。

この 2 つのドキュメントを理解すれば、あなたは決してそのような人物にはなりません。

于 2009-08-05T17:01:19.033 に答える
4

このようなジェネリック パラメーターに基づいて型のインスタンスを作成する機能

新しい T();

于 2009-06-16T18:38:22.347 に答える
4

オブジェクト初期化子内のコレクション初期化子:

MailMessage mail = new MailMessage {
   To = { new MailAddress("a@example.com"), new MailAddress("b@example.com") },
   Subject = "Password Recovery"
};

ツリー全体を 1 つの式で初期化できます。

于 2010-02-09T19:05:23.790 に答える
4

C# コンパイラの落とし穴の 1 つが

where T : Enum

コンパイルされません。「制約を特別なクラス 'System.Enum' にすることはできません」というエラーがスローされます。

于 2010-02-02T22:12:39.037 に答える
4

静的テンプレート クラスが静的メンバーを共有しないという事実を悪用するのが大好きです。

これはスレッドセーフ (作成時) でありDictionary<Type,...>Typeインスタンスがコンパイル時に認識されている場合の安価な代用です。

public static class MyCachedData<T>{
    static readonly CachedData Value;
    static MyCachedData(){
       Value=// Heavy computation, such as baking IL code or doing lots of reflection on a type
    }
}

乾杯、フロリアン

于 2009-10-26T16:45:31.897 に答える
4

protectedアクセサーとアクセサーを組み合わせてinternal、同じアセンブリ内でパブリックにすることができますが、別のアセンブリでは保護されます。これは、フィールド、プロパティ、メソッド、さらには定数で使用できます。

于 2012-02-23T12:34:19.723 に答える
4

Visual Studio の最も便利な機能の 1 つは、"オブジェクト ID の作成" です。これは ID を生成し、オブジェクトに「アタッチ」するため、オブジェクトを見ればどこでも (スレッドに関係なく) ID も表示されます。

デバッグ中に変数のツールチップを右クリックすると、それが表示されます。また、watched/autos/locals 変数でも機能します。

于 2010-03-11T15:01:42.510 に答える
4

列挙値を文字列値に変換する

与えられた列挙型

enum Country
{
    UnitedKingdom, 
    UnitedStates,
    UnitedArabEmirates,
}

それを使用して:

public static void PrintEnumAsString( Country country )
{
    Console.Writeline( country.ToString() );
}

enum 値の名前を文字列として出力します (例: "UnitedKingdom")。

于 2009-11-25T17:16:48.400 に答える
4

これは、静的コンストラクターに関連しています。これは、静的破棄 (つまり、プログラムの終了時にリソースをクリーンアップする) を実行するためのメソッドです。

まずクラスから:

class StaticDestructor
{
    /// <summary>
    /// The delegate that is invoked when the destructor is called.
    /// </summary>
    public delegate void Handler();
    private Handler doDestroy;

    /// <summary>
    /// Creates a new static destructor with the specified delegate to handle the destruction.
    /// </summary>
    /// <param name="method">The delegate that will handle destruction.</param>
    public StaticDestructor(Handler method)
    {
        doDestroy = method;
    }

    ~StaticDestructor()
    {
        doDestroy();
    }
}

次に、「静的デストラクタ」に実行させたいクラスのメンバーとして、次のようにします。

private static readonly StaticDestructor destructor = new StaticDestructor
(
    delegate()
    {
        //Cleanup here
    }
);

これは、最終的なガベージ コレクションが発生したときに呼び出されるようになりました。これは、特定のリソースを解放する必要がある場合に役立ちます。

この動作を示す迅速で汚いプログラム:

using System;

namespace TestStaticDestructor
{
    class StaticDestructor
    {
        public delegate void Handler();
        private Handler doDestroy;

        public StaticDestructor(Handler method)
        {
            doDestroy = method;
        }

        ~StaticDestructor()
        {
            doDestroy();
        }
    }

    class SomeClass
    {
        static SomeClass()
        {
            Console.WriteLine("Statically constructed!");
        }

        static readonly StaticDestructor destructor = new StaticDestructor(
            delegate()
            {
                Console.WriteLine("Statically destructed!");
            }
        );
    }

    class Program
    {
        static void Main(string[] args)
        {
            SomeClass someClass = new SomeClass();
            someClass = null;
            System.Threading.Thread.Sleep(1000);
        }
    }
}

プログラムが終了すると、「静的デストラクタ」が呼び出されます。

于 2010-04-05T03:58:57.897 に答える
4

各プリミティブ型の TryParse メソッドは、ユーザー入力を検証するときに最適です。

double doubleValue
if (!Double.TryParse(myDataRow("myColumn"), out doubleValue))
{
    // set validation error
}
于 2008-09-03T15:03:20.693 に答える
4

フレームワーク機能

わかりませんが、VisualStyleRendererとSystem.Windows.Forms.VisualStyles-Namespace全体にかなり驚きました。かなりクール!

于 2008-11-23T17:45:14.367 に答える
4

ジェネリックとCuriously-Recurring Template パターンは、いくつかの静的メソッド/プロパティの宣言に本当に役立ちます。

クラス階層を構築しているとします。

class Base
{
}

class Foo: Base
{
}

class Bar: Base
{
}

ここで、同じ型のパラメーター (または戻り値) または同じ型の静的プロパティを取る必要がある型の静的メソッドを宣言します。たとえば、次のようにします。

class Base
{
    public static Base Get()
    {
        // Return a suitable Base.
    }
}

class Foo: Base
{
    public static Foo Get()
    {
        // Return a suitable Foo.
    }
}

class Bar: Base
{
    public static Bar Get()
    {
        // Return a suitable Bar.
    }
}

これらの静的メソッドが基本的にすべて同じことを行う場合、多くの重複したコードが手元にあります。1 つの解決策は、戻り値のタイプ セーフを削除し、常に type を返すことですBase。ただし、タイプ セーフが必要な場合の解決策は、次のように宣言することBaseです。

class Base<T> where T: Base<T>
{
    public static T Get<T>()
    {
        // Return a suitable T.
    }
}

そしてあなたFooととBarして:

class Foo: Base<Foo>
{
}

class Bar: Base<Bar>
{
}

このようにして、静的メソッドのコピーを自動的に取得します。

これは、 Singletonパターンを基本クラスにカプセル化するのにも驚くほど機能します(以下のコードはスレッド セーフではないことを知っています。要点を示すためだけです)。

public class Singleton<T> where T: Singleton<T>, new()
{
  public static T Instance { get; private set; }

  static Singleton<T>()
  {
    Instance = new T();
  }
}

これにより、シングルトン サブクラスにパラメーターなしのパブリック コンストラクターが必要になりますが、where T: protected new()コンストラクトなしでコンパイル時にそれを回避する方法はありません。ただし、リフレクションを使用して、実行時にサブクラスの保護された/プライベートのパラメーターなしのコンストラクターを呼び出して、それを実現できます。

于 2009-08-07T22:39:32.553 に答える
4

私はこの会話に少し遅れており、以下に貢献したいと思います. 一部の開発者にとっては新しいことかもしれません。

public class User
{
    public long UserId { get; set; }
    public String Name { get; set; }
    public String Password { get; set; }
    public String Email { get; set; }
}

それを宣言して初期化する通常の方法は、コンストラクターなどを使用することです。

User user = new User();
user.UserId = 1;
user.Name = "myname";
etc

しかし、私はそれを初期化する次の方法を学びました。次のように、C# ではなく VB.NET でのみ使用できる演算子のようなものなので、Visual Basic 開発者はそれを気に入るはずです。

User user = new User()
{
    UserId = 1,
    Name = "myname",
    Email = "myemail@domain.com",
    Password = "mypassword"
};
于 2010-02-11T10:37:59.893 に答える
4

Visual Studio ツールバーに検索テキスト ボックスがある場合は、">of Program.cs" と入力して Program.cs ファイルを開くことができます。

于 2009-06-05T20:56:00.313 に答える
4

容認はしませんが、後藤がまだアヒルの飛来物周辺にいることに驚きました

于 2010-06-22T19:57:59.953 に答える
4

これは、データベース アプリケーションの開発者にとってはかなり基本的なことかもしれませんが、null が DBNull.value と同じではないことに気付くのにしばらく時間がかかりました。

データベース レコードの値が null かどうかを確認するには、DBNull.value を使用する必要があります。

于 2008-10-21T19:08:37.363 に答える
4

一般的な制約:

 //Constructor constraint, T has a default empty constructor
class Node<K,T> where T : new() 
{
}

//Reference\Value Type constraints
//T is a struct
public class MyClass<T> where T : struct 

{...}

//T is a reference type
public class MyClass<T> where T : class 

{...}

public class MyClass<T> where T : SomeBaseClass, ISomeInterface 

{...}
于 2009-06-30T07:11:12.670 に答える
3

パーマリンク「C#の隠された機能?」の投稿を参照すると、同じことを実現する別の方法があります-インデント/改行。これをチェックしてください。

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.NewLineOnAttributes = true;
xmlWriterSettings.Indent = true;


XmlWriter xml = XmlWriter.Create(@"C:\file.xml", xmlWriterSettings);

// Start writing the data using xml.WriteStartElement(), xml.WriteElementString(...), xml.WriteEndElement() etc

これが未知の機能かどうかはわかりませんが!

于 2010-04-08T19:30:55.320 に答える
3

メソッドオーバーロードの使用を回避するのに役立つジェネリックメソッドについては知りませんでした。以下は、intとdoubleの数値を出力するためのオーバーロードされたメソッドです。

    private static void printNumbers(int [] intNumbers)
    { 
        foreach(int element in intNumbers)
        {
            Console.WriteLine(element);
        }

    }

    private static void printNumbers(double[] doubleNumbers)
    {
        foreach (double element in doubleNumbers)
        {
            Console.WriteLine(element);
        }
    }

上記の両方に対して1つのメソッドを持つのに役立つジェネリックメソッド

    private static void printNumbers<E>(E [] Numbers)
    {
        foreach (E element in Numbers)
        {
            Console.WriteLine(element);
        }
    }
于 2010-01-05T11:51:22.167 に答える
3

参考のためにのみ-拡張メソッドを使用した列挙型二項演算。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace BinaryOpGenericTest
{
    [Flags]
    enum MyFlags
    {
        A = 1,
        B = 2,
        C = 4

    }

    static class EnumExtensions
    {
        private static Dictionary<Type, Delegate> m_operations = new Dictionary<Type, Delegate>();

        public static bool IsFlagSet<T>(this T firstOperand, T secondOperand) 
                                                  where T : struct
        {

            Type enumType = typeof(T);


            if (!enumType.IsEnum)
            {
                throw new InvalidOperationException("Enum type parameter required");
            }


            Delegate funcImplementorBase = null;
            m_operations.TryGetValue(enumType, out funcImplementorBase);

            Func<T, T, bool> funcImplementor = funcImplementorBase as Func<T, T, bool>;

            if (funcImplementor == null)
            {
                funcImplementor = buildFuncImplementor(secondOperand);
            }



            return funcImplementor(firstOperand, secondOperand);
        }


        private static Func<T, T, bool> buildFuncImplementor<T>(T val)
                                                            where T : struct
        {
            var first = Expression.Parameter(val.GetType(), "first");
            var second = Expression.Parameter(val.GetType(), "second");

            Expression convertSecondExpresion = Expression.Convert(second, typeof(int));
            var andOperator = Expression.Lambda<Func<T, T, bool>>(Expression.Equal(
                                                                                                       Expression.And(
                                                                                                            Expression.Convert(first, typeof(int)),
                                                                                                             convertSecondExpresion),
                                                                                                       convertSecondExpresion),
                                                                                             new[] { first, second });
            Func<T, T, bool> andOperatorFunc = andOperator.Compile();
            m_operations[typeof(T)] = andOperatorFunc;
            return andOperatorFunc;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            MyFlags flag = MyFlags.A | MyFlags.B;

            Console.WriteLine(flag.IsFlagSet(MyFlags.A));            
            Console.WriteLine(EnumExtensions.IsFlagSet(flag, MyFlags.C));
            Console.ReadLine();
        }
    }
}
于 2009-02-03T18:42:13.857 に答える
3

ViewStateゲッターはワンライナーにすることができます。

デフォルト値の使用:

public string Caption
{
    get { return (string) (ViewState["Caption"] ?? "Foo"); }
    set { ViewState["Caption"] = value; }
}

public int Index
{
    get { return (int) (ViewState["Index"] ?? 0); }
    set { ViewState["Index"] = value; }
}

デフォルトとしてnullを使用する:

public string Caption
{
    get { return (string) ViewState["Caption"]; }
    set { ViewState["Caption"] = value; }
}

public int? Index
{
    get { return (int?) ViewState["Index"]; }
    set { ViewState["Index"] = value; }
}

これは、辞書に裏打ちされたすべてのものに対して機能します。

于 2008-11-15T07:14:26.467 に答える
3

最初に - DebuggerTypeProxy

[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable : Hashtable
{
    private const string TestString = 
        "This should not appear in the debug window.";

    internal class HashtableDebugView
    {
        private Hashtable hashtable;
        public const string TestStringProxy = 
            "This should appear in the debug window.";

        // The constructor for the type proxy class must have a 
        // constructor that takes the target type as a parameter.
        public HashtableDebugView(Hashtable hashtable)
        {
            this.hashtable = hashtable;
        }
    }
}

2 番目に:

ICustomTypeDescriptor

于 2009-09-10T11:21:28.523 に答える
3

.NET 3.5 でステートメント ラムダを使用する場合、間違いなく Func<> 型です。これらはカスタマイズ可能な機能を可能にし、ユーザーがカスタマイズ可能なオブジェクトをサブクラス化したり、ユーザーが監視したいボタンやキーをリストする変数を追跡するなどの限られたシステムに頼ったりすることなく提供するのに非常に役立ちます。また、通常のメソッドと同じように呼び出すことができ、変数のように割り当てることができます。私が考えることができる唯一の欠点は、引数が 5 つに制限されていることです! その時点で、別の解決策を検討したいかもしれませんが... 編集: いくつかの例を提供します。

...
public Func<InputHelper, float> _horizontalCameraMovement = (InputHelper input) => 
{
    return (input.LeftStickPosition.X * _moveRate) * _zoom;
}
public Func<InputHelper, float> _verticalCameraMovement = (InputHelper input) => 
{
    return (-input.LeftStickPosition.Y * _moveRate) * _zoom;
}
...
public void Update(InputHelper input)
{
    ...
    position += new Vector2(_horizontalCameraMovement(input), _verticalCameraMovement(input));
    ...
}

この例では、任意の計算を行い、カメラの移動量を決定する float を返す関数を作成できます。最高のコードではありませんが、要点はわかります。

private int foo;
public int FooProperty {
    get
    {
        if (_onFooGotten() == true)
            return _foo;
    }
    set
    {
        if (onFooSet() == true)
            _foo = value;
    }
}
...
public Func<bool> _onFooGotten = () => 
{
    //do whatever...
    return true;
}
public Func<bool> _onFooSet = () =>
{
    //do whatever...
    return true;
}

これは最良の例ではありませんが (この使用法についてはまだ詳しく調べていないため)、デリゲートの手間をかけずにラムダ関数を使用してクイック イベント レイザーを作成する例を示しています。編集:別のものを考えました。Nullable!C# がオプションのパラメーターに最も近いもの。

于 2009-06-04T08:41:48.907 に答える
3

これ自体が秘密かどうかはわかりませんが、System.Linq に追加された Enumerable (IEnumerable に追加) クラスが気に入りました。

http://msdn.microsoft.com/en-us/library/system.linq.enumerable_members.aspx

yield キーワードはすでにリストされていますが。イテレータ ブロックは驚くべきものです。それらを使用して、それらが互いに素であるかどうかをテストするリストを作成しました。基本的に、値を1つずつ返し、いつでも停止する関数を実行できます。

ああ、もう最適化できなくなったら、世界最高のクラスを忘れそうになりました。バックグラウンドワーカー!!!!

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

于 2010-01-13T09:31:52.353 に答える
3

次のものは隠されているわけではありませんが、非常に暗黙的です。次のようなサンプルがここで公開されているかどうかはわかりませんが、利点があるかどうかはわかりません (おそらく何もない) が、「奇妙な」コードを示してみます。次のサンプルforは、C# のファンクター (デリゲート/匿名デリゲート [ラムダ]) とクロージャーを介してステートメントをシミュレートします。ifif/elsewhileなどの他のフロー ステートメントdo/whle もシミュレートされますが、よくわかりませんswitch(おそらく、私は怠けすぎです :))。わかりやすくするために、サンプル ソース コードを少し圧縮しました。

private static readonly Action EmptyAction = () => { };
private static readonly Func<bool> EmptyCondition = () => { return true; };

private sealed class BreakStatementException : Exception { }
private sealed class ContinueStatementException : Exception { }
private static void Break() { throw new BreakStatementException(); }
private static void Continue() { throw new ContinueStatementException(); }

private static void For(Action init, Func<bool> condition, Action postBlock, Action statement) {
    init = init ?? EmptyAction;
    condition = condition ?? EmptyCondition;
    postBlock = postBlock ?? EmptyAction;
    statement = statement ?? EmptyAction;
    for ( init(); condition(); postBlock() ) {
        try {
            statement();
        } catch ( BreakStatementException ) {
            break;
        } catch ( ContinueStatementException ) {
            continue;
        }
    }
}

private static void Main() {
    int i = 0; // avoiding error "Use of unassigned local variable 'i'" if not using `for` init block
    For(() => i = 0, () => i < 10, () => i++,
        () => {
            if ( i == 5 )
                Continue();
            Console.WriteLine(i);
        }
    );
}

私が間違っていなければ、このアプローチは関数型プログラミングの実践にかなり関連しています。私は正しいですか?

于 2009-10-29T23:44:23.133 に答える
3

DataGridView にプロパティが表示されないようにします。

[System.ComponentModel.Browsable(false)]
public String LastActionID{get; private set;}

コンポーネント (DataGrid や DataGridView など) のわかりやすい表示を設定できます。

[System.ComponentModel.DisplayName("Last Action")]
public String LastAction{get; private set;}

バッキング変数の場合、直接アクセスしたくない場合は、これが難しくなります。

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    private DataController p_dataSources;
于 2009-08-14T20:53:32.227 に答える
3

IQueryable プロジェクションを返す

protected void LdsPostings_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{   
    var dc = new MyDataContext();
    var query = dc.Posting.AsQueryable();

    if (isCondition1)
    {
        query = query.Where(q => q.PostedBy == Username);
        e.Result = QueryProjection(query);
        return;
    }

    ...

    if (isConditionN)
    {
        query = query.Where(q => q.Status.StatusName == "submitted");
        query = query.Where(q => q.ReviewedBy == Username);
        e.Result = QueryProjection(query);
        return;
    }
}

プロジェクションを複数回コーディングするのではなく、単一のメソッドを作成します。

private IQueryable QueryProjection(IQueryable<Posting> query)
{
    return query.Select(p => new
    {
        p.PostingID,
        p.Category.CategoryName,
        p.Type.TypeName,
        p.Status.StatusName,
        p.Description,
        p.Updated,
        p.PostedBy,
        p.ReviewedBy,
    });
}
于 2008-08-28T14:49:03.490 に答える
3

ThreadStaticAttribute は私のお気に入りです。また、NonSerializableAttribute も便利です。(私がリモーティングを使用して多くのサーバー関連の作業を行っていることがわかりますか?)

于 2008-11-01T19:48:28.017 に答える
3
double dSqrd = Math.Pow(d,2.0); 

よりも正確です

double dSqrd = d * d; // Here we can lose precision
于 2008-10-13T22:29:09.880 に答える
3

項目のリストからカンマ区切りの文字列を作成しようとしている場合:

string[] itemList = { "Example 1", "Example 2", "Example 3" };
CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
commaStr.AddRange(itemList);
//outputs Example 1,Example 2,Example 3

別の例については、こちらをご覧ください。

于 2009-07-23T19:26:07.540 に答える
3

ContextBoundObject

.NET ほど C# のものではありません。大変な作業になる可能性がありますが、これは DI を達成する別の方法です。そして、あなたはそれを継承しなければなりません。

http://msdn.microsoft.com/en-us/library/system.contextboundobject.aspx

カスタムロギング属性でクラス/メソッドを装飾するときにロギングを追加するために使用しました。

于 2008-10-09T20:37:13.477 に答える
3

最近、String.Join メソッドについて学びました。クエリで選択する列などの文字列を作成するときに非常に便利です。

于 2010-06-09T14:39:44.047 に答える
2

C ++とC#の間の相互運用を処理する際に、多くの人はC ++/CLIが優れたオプションであることを認識していません。

C ++DLLとC++ DLLに依存するC#DLLがあるとします。多くの場合、最も簡単な手法は、C ++ DLLの一部(またはすべて)のモジュールを/clrスイッチを使用してコンパイルすることです。C#でC ++ DLLを呼び出すには、マネージC++ラッパークラスをC++DLLに記述します。C ++ /CLIクラスはC#よりもはるかにシームレスにネイティブC ++コードを呼び出すことができます。これは、C++コンパイラが自動的にP/呼び出しを生成し、相互運用専用のライブラリに加えて、pin_ptrなどの相互運用用の言語機能を備えているためです。また、マネージコードとネイティブコードを同じバイナリ内で共存させることができます。

C#側では、他の.NETバイナリと同じようにDLLを呼び出すだけです。

于 2009-05-08T17:43:21.533 に答える
2

これが通常のASP.NETリピーターonItemDataboundキャストコードよりもパフォーマンスが良いか悪いかはわかりませんが、とにかくここに私の5セントがあります。

MyObject obj = e.Item.DataItem as MyObject;
if(obj != null)
{
  //Do work
}
于 2008-08-18T17:06:41.957 に答える
2

IEnumerable オブジェクトを明示的に作成せずに yield を介して IEnumerable を取得する別の方法

public IEnumerable<Request> SomeMethod(IEnumerable<Request> requests)
{
    foreach (Request request in requests)
       yield return DoSomthing(request);
}
于 2010-01-26T19:16:16.897 に答える
2

PreviousPage プロパティ:

「制御を現在のページに移したページを表す System.Web.UI.Page。」

とても便利です。

于 2008-09-02T02:10:06.660 に答える
2

P/Invokeのほとんどは少し奇妙です。

属性の例:

[DllImport ("gdi32.dll")] 
[return : MarshalAs(UnmanagedType.I4)]
[StructLayout(LayoutKind.Sequential)]
于 2010-03-02T05:16:54.683 に答える
2

Nullable 型を使用する必要がある場合は、疑問符表記ではなく Nullable<.T> を使用する方がよいと思います。魔法が起こっていることが目障りなほど明らかです。ただし、なぜ Nullable<.bool> を使用したいのかはわかりません。

パラメーターが渡されない可能性がある VB.NET Web サービスでは(パートナーの要求が一貫していないか信頼できないため) 、提案された型(「検索要求の場合」のブール値)に対して検証を渡す必要がありました。「経営陣からの別の要求」にチョークで書きます...

...そして、はい、これらのことを行うのが正しい方法ではないと考える人がいることは知っていますが、IsSearchRequest As Nullable(Of Boolean) のおかげで、その夜は気が狂いそうになりました!

于 2008-08-18T00:10:35.893 に答える
2

BCL の一部の同時実行ユーティリティは、非表示の機能として認定される場合があります。

System.Threading.Monitor などは lock キーワードによって内部的に使用されます。明らかに C# では lock キーワードが望ましいですが、下位レベルでの処理方法を知っておくと役立つ場合もあります。C++/CLI でロックする必要があったため、コードのブロックを Monitor.Enter() と Monitor.Exit() の呼び出しで囲みました。

于 2008-09-19T14:39:16.503 に答える
2

エスケープ文字を含む文字列の前の @ の使用。基本的に、物理パスを使用して文字列変数に割り当てる場合、文字列にエスケープ文字が存在する場合、誰もが「\」を使用します。

例 string strPath="D:\websites\web1\images\";

ただし、文字列値の前に @ を使用すると、エスケープ文字を無視できます。

例: string strPath=@"D:\websites\web1\images\";

于 2009-10-20T10:04:34.167 に答える
2

上記の List.ForEach の言及を見ました。2.0 では、一連の述語ベースのコレクション操作 (Find、FindAll、Exists など) が導入されました。匿名デリゲートと組み合わせると、3.5 のラムダ式の単純さをほぼ実現できます。

于 2008-09-09T03:30:49.463 に答える
2

ラムダが登場する前は、匿名デリゲートです。これは、Ruby の blockgiven に似たブランケット コードに使用できます。ただし、これまでのところ.NET 2.0に固執したいので、ラムダがどのように機能するかをテストしていません。

たとえば、HTML タグを閉じることを忘れないようにしたい場合は、次のようにします。

MyHtmlWriter writer=new MyHtmlWriter();
writer.writeTag("html", 
  delegate ()
  { 
    writer.writeTag("head", 
       delegate() 
       { 
           writer.writeTag("title"...);
       }
    )
  })

ラムダがオプションであれば、よりクリーンなコードが得られると確信しています:)

于 2008-09-19T16:26:29.023 に答える
2

@ロビー・ロケットパンツ

「しかし、私の本能は、これにより、最大 2 つの型キャスト操作が最大 1 つに削減されることを教えてくれます。」

例 1 で提案したように (is & as を使用して) キャストを実行すると、「is」演算子が 2 回呼び出されます。「c = obj as MyClass」を実行すると、最初に裏で「is」が呼び出され、失敗すると単に null が返されるためです。

例2で提案したようにキャストを行うと、

c = (MyClass)obj

次に、これは実際に「is」操作を再度実行し、そのチェックに失敗すると、例外 (InvalidCastException) をスローします。

したがって、軽量の動的キャストを実行したい場合は、提供された 3 番目の例を実行するのが最善です。

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

if (c != null)
{
}

MyClass c = obj as MyClass;

if (c != null)
{
}

どちらがより速く、より簡潔で、より明確であるかがわかります。

于 2008-09-05T09:14:04.713 に答える
2

Delegate.CreateDelegate を使用してプライベート メソッドを呼び出すこのトリックは、非常に巧妙です。

var subject = new Subject();
var doSomething = (Func<String, String>)
    Delegate.CreateDelegate(typeof(Func<String, String>), subject, "DoSomething");
Console.WriteLine(doSomething("Hello Freggles"));

これが役立つコンテキストです

于 2010-02-16T09:58:48.280 に答える
2

慎重に使用すると、反射は非常に強力です。電子メール テンプレート システムで使用しました。テンプレート マネージャーにはオブジェクトが渡され、html テンプレートには、リフレクションを使用して渡されたオブジェクトから取得できるプロパティを参照するフィールドが埋め込まれます。とてもうまくいきました。

于 2009-06-03T15:37:49.650 に答える
1

サードパーティの拡張機能が許可されている場合は、C5Microsoft CCR(簡単な紹介についてはこのブログ投稿を参照)を知っておく必要があります。

C5は.Netのやや不足しているコレクションライブラリ(Set ???ではない)を補完し、CCRは並行プログラミングを容易にします(Parallel Extensionsとマージされる予定だと聞きました)。

于 2008-09-19T19:20:30.743 に答える
1

周囲のクラスのジェネリックタイプに応じて、静的フィールドを分離します。

    public class StaticConstrucEx2Outer<T> {

 // Will hold a different value depending on the specicified generic type
 public T SomeProperty { get; set; }

 static StaticConstrucEx2Outer() {
  Console.WriteLine("StaticConstrucEx2Outer " + typeof(T).Name);
 }

 public class StaticConstrucEx2Inner<U, V> {

  static StaticConstrucEx2Inner() {

   Console.WriteLine("Outer <{0}> : Inner <{1}><{2}>",
    typeof(T).Name,
    typeof(U).Name,
    typeof(V).Name);
  }

  public static void FooBar() {}
 }

 public class SCInner {

  static SCInner() {
   Console.WriteLine("SCInner init <{0}>", typeof(T).Name);
  }

  public static void FooBar() {}
 }
}


StaticConstrucEx2Outer<int>.StaticConstrucEx2Inner<string, DateTime>.FooBar();
StaticConstrucEx2Outer<int>.SCInner.FooBar();

StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, DateTime>.FooBar();
StaticConstrucEx2Outer<string>.SCInner.FooBar();

StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, Int16>.FooBar();
StaticConstrucEx2Outer<string>.SCInner.FooBar();

StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, UInt32>.FooBar();

StaticConstrucEx2Outer<long>.StaticConstrucEx2Inner<string, UInt32>.FooBar();

次の出力を生成します

Outer <Int32> : Inner <String><DateTime>
SCInner init <Int32>

Outer <String> : Inner <String><DateTime>
SCInner init <String>

Outer <String> : Inner <String><Int16>

Outer <String> : Inner <String><UInt32>

Outer <Int64> : Inner <String><UInt32>
于 2010-05-16T09:55:53.540 に答える
1

例外フィルター。したがって、「非表示」であるため、コンパイル後のパッチなしでは (少なくとも C# からは) それらを使用することさえできません;)

于 2009-07-17T14:29:23.230 に答える
1

隠れていませんが、かなりきれいです。これは、条件に基づいて値を割り当てるだけの単純な if-then-else のより簡潔な代替方法だと思います。

string result = 
              i < 2 ?               //question
              "less than 2" :       //answer
              i < 5 ?               //question
             "less than 5":         //answer   
              i < 10 ?              //question
              "less than 10":       //answer
              "something else";     //default answer 
于 2009-03-31T04:18:58.253 に答える
1

いくつか ??奇妙:)

Delegate target =
  (target0 = target as CallTargetWithContext0) ??
  (target1 = target as CallTargetWithContext1) ??
  (target2 = target as CallTargetWithContext2) ??
  (target3 = target as CallTargetWithContext3) ??
  (target4 = target as CallTargetWithContext4) ??
  (target5 = target as CallTargetWithContext5) ??
  ((Delegate)(targetN = target as CallTargetWithContextN));

何らかの理由で必要な最後のキャストに注意するのは興味深いことです。バグか仕様か?

于 2008-09-23T07:45:27.323 に答える
1

ガベージ コレクターがオブジェクトのファイナライザーを実行するのを防ぎたい場合は、単にGC.SuppressFinalize(object);. 同様にGC.KeepAlive(object);、ガベージ コレクターがそのオブジェクトを参照して収集するのを防ぎます。少なくとも私の経験ではあまり一般的に使用されていませんが、念のため知っておくと便利です。

于 2009-06-03T14:53:50.137 に答える
1

イベントの発生についてオブジェクト間で (a) 同期的に通信する必要がある場合は、ISynchronizeInvokeと呼ばれる特別な目的のインターフェイスがあります。

MSDN の記事を引用 (リンク):

このインターフェイスを実装するオブジェクトは、イベントが発生したという通知を受け取ることができ、イベントに関するクエリに応答できます。このようにして、クライアントは、最初の要求の完了に依存する後続の要求を送信する前に、1 つの要求が処理されたことを確認できます。

一般的なラッパーは次のとおりです。

protected void OnEvent<T>(EventHandler<T> eventHandler, T args) where T : EventArgs
{
    if (eventHandler == null) return;

    foreach (EventHandler<T> singleEvent in eventHandler.GetInvocationList())
    {
        if (singleEvent.Target != null && singleEvent.Target is ISynchronizeInvoke)
        {
            var target = (ISynchronizeInvoke)singleEvent.Target;

            if (target.InvokeRequired) {
                target.BeginInvoke(singleEvent, new object[] { this, args });
                continue;
            }
        }
        singleEvent(this, args);
    }
}

使用例は次のとおりです。

public event EventHandler<ProgressEventArgs> ProgressChanged;

private void OnProgressChanged(int processed, int total)
{
    OnEvent(ProgressChanged, new ProgressEventArgs(processed, total));
}
于 2009-08-05T17:20:36.187 に答える
1

#Region ディレクティブを使用してコードを文書化する方法のヒントを次に示します。

于 2008-11-18T10:54:30.593 に答える
0

これが隠し機能 ("") かどうかはわかりません。任意の文字列関数。

于 2010-02-19T03:54:47.300 に答える