0

動的またはオブジェクトから変数型にキャストすることは可能ですか? ターゲット変数の型は 1 つのジェネリック クラスであり、特定のデータ型のみが異なります。

抽象的な解決策を探していますが、状況は次のとおりです。異なるエンティティに対して単一のLinq2SQLコマンドが必要です-EntityFrameworkコンテキストのGetProperty + GetValueを実行できますが、正確な型にキャストする必要がありますが、これらは変数から来ています入力 - DB テーブルの名前。

私が持っているものの例:

 Type NewType = typeof(System.Data.Objects.ObjectSet<>);
 NewType.MakeGenericType(new Type[] {"...some type here that's variable accordint to user input - like Person, Address, Contact, ..."});            
 Object MyObject = Context.GetType().GetProperty("the same variable like above - Person, Address,...", BindingFlags.Public | BindingFlags.Instance).GetValue(Context, null); // this is EntityFramework Context

必要なものの例ですが、それを行う方法がわかりません:

 NewType CastedObject = (NewType) MyObject;
 // or
 NewType CastedObject = Convert.ChangeType(MyObject, NewType);
 // or
 NewType CastedObject = MyObject as NewType;

だから私はこれを行うことができます:

 (from x in CastedObject where x.ID == ID select x).FirstOrDefault();

PHPに精通している人のために、私はこれをやろうとしています:

 (from x in Context.$tablename where x.ID == ID select x).FirstOrDefault();
4

2 に答える 2

0

は実行時の型なのでNewType、コンパイル時の型の変数をどのように持つことができますNewTypeか? コンパイラは、すべての変数の「宣言された」型を認識している必要があります。だからあなたが望むことは不可能です。

できることは にキャストすることです。次に、次のようなものがコンパイルされます(ただし、コンパイル時の型チェックはありません)。MyObjectdynamicforeach (var x in CastedToDynamic)

dynamicただし、式でLINQ を使用することはできません。次のように書き直す必要があります。

    dynamic found = null;
    foreach (var x in CastedToDynamic)
    {
      if (x.ID == ID)
      {
        found = x;
        break;
      }
    }

注: のどのオーバーロード==を使用するかは、実行時に決定されます。したがってID、 が (boxed)System.Guidであっても、その構造体内==で defined のオーバーロードを (unbox して) 呼び出します。==したがって、これは機能します。

于 2013-03-21T16:36:09.257 に答える
0

このようなものは、あなたが見ているものに到達する可能性があります(反射に大きく依存しています)

        List<dynamic> mylist = new List<dynamic>();
        dynamic data = new ExpandoObject();
        data.Foo = "foo";
        data.ID = 1;
        mylist.Add(data);

        data = new ExpandoObject();
        data.Foo = "foobar";
        data.ID = 2;
        mylist.Add(data);


        data = new ExpandoObject();
        data.Foo = "foobar2";
        data.ID = 2;
        mylist.Add(data);

        data = new ExpandoObject();
        data.Foo = "foobar2";
        data.ID = 3;
        mylist.Add(data);

        int idiminterestedin = 2;

        var dynamicselected = mylist.Select(d=>((IDictionary<string,object>)d)).Where(d=>
        {
            object id;
            if (d.TryGetValue("ID",out id))
            {
                return (id is int) && (int)id == idiminterestedin;
            }
            return false;
        });

        foreach (var v in dynamicselected)
        {
            Console.WriteLine(v["Foo"]);
        }

        Console.ReadLine();

私はおそらく ExpandoObject をスキップして、辞書に直行します:

        Dictionary<string, object> data = new Dictionary<string, object>();
        data["Foo"] = "foo";
        data["ID"] = 1;

次に、一般的な拡張関数を作成します。

static class ExptensionFunction
{
    static T GetValueAs<T>(this Dictionary<string, object> obj, string key)
    {
        return (T)obj[key];
    }

    static bool TryGetValueAs<T>(this Dictionary<string, object> d, string key, out T value)
    {
        object id;
        if (d.TryGetValue(key, out id))
        {
            if (id is T)
            {
                value = (T)id;
                return true;
            }
        }

        value = default(T);
        return false;
    }

    static IEnumerable<Dictionary<string, object>> GetValuesWithKey<T>(this List<Dictionary<string, object>> list, string key, T value)
    {
        return list.Where(d =>
        {
            T id;
            if (d.TryGetValueAs<T>(key, out id))
            {
                return id.Equals(value);
            }
            return false;
        });
    }
}

これに触発されました:

匿名型を動的に作成しますか?

作成後に匿名型にプロパティを追加する

于 2013-03-21T17:41:43.743 に答える