2009-05-17 9 views
20

私はLinqクエリによってデータオブジェクトが作成されています。データグリッド内のフォーカスされた行が変更されたら、そのオブジェクトのプロパティの1つと同じ変数を設定する必要があります。匿名型からプロパティの値を取得するにはどうすればよいですか?

私が試した...

var selectedObject = view.GetRow(rowHandle); 
_selectedId = selectedObject.Id; 

...しかし、コンパイラは、すべてで、このために気にしません(「組み込みステートメントは、宣言または標識さ陳述することはできません」)。

プロパティにアクセスしやすくする必要があるようです。実行時にオブジェクトを調べると、予想されるすべてのプロパティが表示されます。アクセス方法はわかりません。

匿名オブジェクトのプロパティにアクセスするにはどうすればよいですか?明確化のため

編集:

私はDevExpress社XtraGridコントロールを使用してすることが起こります。このコントロールには、いくつかの異なるオブジェクトで構成されているLinqクエリがロードされています。したがって、データが実際に既に持っているいずれかのクラスに適合していない(つまり、これを何かにキャストできません)。

私は.NET 3.5を使用しています。

私はこのようになります匿名型を取得view.GetRow(rowHandle)メソッドの結果を表示すると:

{ ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 } 

を私の目的は私が行うことができますので、この匿名型からClientIdをを得ることです他のもの(そのクライアントレコードを含むフォームをロードするなど)。

私は初期の回答でいくつかの提案を試みましたが、このClientIdを得ることができなかった点に到達できませんでした。

+0

識別子「ビュー」の正確なタイプは何ですか? – AnthonyWJones

+0

"View"はDevExpressのGridViewコントロールです。 –

答えて

43

あなたは反射を使用しようとしたことがありますか?サンプルコードスニペットは次のとおりです。

// use reflection to retrieve the values of the following anonymous type 
var obj = new { ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }; 
System.Type type = obj.GetType(); 
int clientid = (int)type.GetProperty("ClientId").GetValue(obj, null); 
string clientname = (string)type.GetProperty("ClientName").GetValue(obj, null); 

// use the retrieved values for whatever you want... 
+0

ありがとうございますabdoul、あなたのコードはかなり理解しやすいです。私は最近、匿名のタイプを取得する際に問題が発生しました:http://stackoverflow.com/questions/3534969/only-parameterless-constructors-and-initializers-are-support-in-linq-to-entitie 私は質問を残しました。週末にいくつかの検索と作業をした後、私はこのページに来て本当に私の一日を作りました。 – Developer

+0

それはまさに私がSOを愛する理由です – Bergkamp

+0

本当に、あまりにも素晴らしい答え!これは私が2週間から探していたものです!どうもありがとうございます! – KomalJariwala

17

匿名型の問題の1つは、関数間で使用するのが難しいということです。匿名型を「名前付け」する方法はないため、それらの間にキャストすることは非常に困難です。これにより、メタデータに表示され、ユーザー定義されているものの型式として使用できなくなります。

上記のどのAPIを使用しているのか正確には分かりません。しかし、APIが強く型付けされた匿名型を返すことはできません。したがって、そのselectedObject内の推測がオブジェクトに入力されます。 C#3.0以下では動的アクセスがサポートされていないため、実行時に利用可能な場合でもプロパティIDにアクセスすることはできません。

あなたは完全なタイプを作成し、使用して、

  • データグリッドを埋めるために、多くのものをそれを使用
  • プロパティをつかむために、この

    • 使用反射を回避するために、次のいずれかにする必要がありますハック匿名型は、キャスト

    EDIT

    は、ここでそれはハックだ理由は、それがこれを破ることは非常に簡単だということです

    public T AnonymousTypeCast<T>(object anonymous, T typeExpression) { 
        return (T)anonymous; 
    } 
    
    ... 
    object obj = GetSomeAnonymousType(); 
    var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 }); 
    

    キャストハック匿名型を行う方法上のサンプルです。たとえば、匿名型が最初に作成されたメソッドの場合です。その型に別のプロパティを追加すると、上記のコードはコンパイルされますが、実行時には失敗します。

  • +0

    「ハッキーな匿名の型キャスト」は何ですか? – AnthonyWJones

    +0

    @AnthonyWJones、私はハッキーな匿名型のキャストの例を追加しました – JaredPar

    +0

    この回答ありがとうございます。とても素晴らしく洗練されたソリューションです。 これには欠点が1つしかありません。匿名オブジェクトが別のアセンブリから取得された場合は機能しません。これは、メソッドから匿名オブジェクトを返すことは決してないはずですが、誰もがそれを知っているわけではないので、残念ながらこれを正確に行うライブラリに対処する必要があります。 –

    0

    これは間違っている可能性があります(コードが不足している可能性があります)が、列にインデックスを付ける必要がないので、必要な列を選択できますか? 「ID」は、あなたがしたい列の場合や、あなたがこのような何かをやっている必要があります。

    var selectedObject = view.GetRow(rowHandle); 
    _selectedId = selectedObject["Id"]; 
    

    これは私がデータグリッド内の列の内容をつかむだろう方法です。列自体が匿名型の場合、私は気にしませんが、プリミティブ型の名前付き列を取得するだけであれば、これはうまくいくはずです。

    1

    JaredParが正しく推測すると、GetRow()の戻り値の型はobjectです。前に、このアプローチは、のような同様の欠点説明「ハック匿名型はキャスト」している

    int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId"); 
    

    :DevExpress社のグリッドで作業する場合、あなたはこのような目的の値を抽出することができますが、列を識別するための魔法の文字列を必要とするプラスオブジェクトからint型への型キャスト

    2

    私が匿名型を渡して再作成しようとしていたとき、私は最終的にオブジェクトの操作を処理するラッパーを書く方が簡単であることを発見しました。ここにそれに関するブログ記事へのリンクがあります。

    http://somewebguy.wordpress.com/2009/05/29/anonymous-types-round-two/

    最終的に、あなたのコードは次のようになります。

    //create an anonymous type 
    var something = new { 
        name = "Mark", 
        age = 50 
    }; 
    AnonymousType type = new AnonymousType(something); 
    
    //then access values by their property name and type 
    type.With((string name, int age) => { 
        Console.Write("{0} :: {1}", name, age); 
    }); 
    
    //or just single values 
    int value = type.Get<int>("age"); 
    
    0

    希望すると、私は別のリストを取得する必要があるインターフェースリストを渡します。まず、匿名の型リストを取得し、それをオブジェクトリストに転送するために歩きます。

    private List<StockSymbolResult> GetDistinctSymbolList(List<ICommonFields> l) 
          { 
           var DistinctList = (
             from a 
             in l 
             orderby a.Symbol 
             select new 
             { 
              a.Symbol, 
              a.StockID 
             }).Distinct(); 
    
           StockSymbolResult ssr; 
           List<StockSymbolResult> rl = new List<StockSymbolResult>(); 
           foreach (var i in DistinctList) 
           { 
               // Symbol is a string and StockID is an int. 
            ssr = new StockSymbolResult(i.Symbol, i.StockID); 
            rl.Add(ssr); 
           } 
    
           return rl; 
          } 
    
    17

    キー

    public static T GetValueFromAnonymousType<T>(object dataitem, string itemkey) { 
        System.Type type = dataitem.GetType(); 
        T itemvalue = (T)type.GetProperty(itemkey).GetValue(dataitem, null); 
        return itemvalue; 
    } 
    

    与えられた例のためのデータ項目の値を取得するための汎用的な解決策:あなたはこのような匿名型のプロパティをループすることができます

    var dataitem = /* Some value here */; 
    bool ismember = TypeUtils.GetValueFromAnonymousType<bool>(dataitem, "IsMember"); 
    
    +0

    私はこの解決策が匿名型を宣言する次善策であることを発見しました。ありがとう。 – DoomerDGR8

    0

    var obj = new {someValue = "hello", otherValue = "world"}; 
    foreach (var propertyInfo in obj.GetType().GetProperties() { 
        var name = propertyInfo.Name; 
        var value = propertyInfo.GetValue(obj, index: null); 
        ... 
    } 
    
    0

    DevExpre ssのxtraGridViewには、このGetRowCellDisplayText(int rowHandle、GridColumn列)のようなメソッドがあります。このメソッドでは、次のコードは匿名型からIDを返します。

    var _selectedId = view.GetRowCellDisplayText(rowHandle, "Id"); 
    

    これは「どのように私は匿名オブジェクトのプロパティへのアクセスを得ることができますか?」という質問に対する答えを提供していませんが、それはまだ、問題の根本的な原因を解決しようとしています。

    私はdevXpressバージョン11.1でこれを試しました。この質問は、ほぼ2.5年前に最初に尋ねられました。おそらく質問の作成者が回避策を見つけたか、解決策を見つけた可能性があります。それでも、誰かを助けるかもしれないように私はまだ答えています。

    11

    リフレクションを使用せずに、実行時に匿名型のプロパティにアクセスするためにダイナミック型を使用できます。

    var aType = new { id = 1, name = "Hello World!" }; 
    //... 
    //... 
    dynamic x = aType; 
    Console.WriteLine(x.name); // Produces: Hello World! 
    

    ここで動的な型について詳しく読む:http://msdn.microsoft.com/en-us/library/dd264736.aspx

    +0

    シンプルでエレガントな私はそれを考えていないと恥じています:) – percebus

    0

    をあなたは何をしているか知っているとするとき、あなたのコードの変更ランタイムエラーを取得するのを恐れていない場合、あなたはdynamicとして、あなたの行データをキャストすることができます:

    var data = view.GetRow(rowHandle) as dynamic; 
    
    int clientId  = data.ClientID; 
    string clientName = data.ClientName; 
    int jobs   = data.Jobs 
    

    いいえコンパイル時の検証。しかし、うまくいくはずです。

    0
    var result = ((dynamic)DataGridView.Rows[rowNum].DataBoundItem).value; 
    
    +0

    これは、リストの属性の値を取得する最も簡単な方法です(DataGridView) –

    関連する問題