Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast to Anonymous Type

I had the following problem today, and I was wondering if there is a solution for my problem.

My idea was to build anonymous classes and use it as a datasource for a WinForm BindingSource:

public void Init() {     var option1 = new                   {                       Id = TemplateAction.Update,                       Option = "Update the Templates",                       Description = "Bla bla 1."                   };      var option2 = new                   {                       Id = TemplateAction.Download,                       Option = "Download the Templates",                       Description = "Bla bla 2."                   };      var list = new[] {option1, option2}.ToList();      bsOptions.DataSource = list; // my BindingSource      // cboTemplates is a ComboBox     cboTemplates.DataSource = bsOptions;      cboTemplates.ValueMember = "Id";     cboTemplates.DisplayMember = "Option";      lblInfoTemplates.DataBindings.Add("Text", bsOptions, "Description"); } 

That works fine so far.

The problem I had is to get Id out of the "Current" property of the BindingSource, because I can't cast it back to the Anonymous Type:

private void cmdOK_Click(object sender, EventArgs e) {     var option = (???)bsOptions.Current; } 

I guess there is no way to find out the type of "Current" and access the "Id" Property? Maybe someone has a good solution...

I know there are other (and also better) ways to get the Id (Reflection, reading the value from the ComboBox, not using anonymous tpyes,...) I'm just courious if it's possible to get the Type out of bsOptions.Current in an elegant way.

like image 963
gsharp Avatar asked Sep 11 '09 08:09

gsharp


People also ask

How do I change my class type to Anonymous?

Convert anonymous type(s) into a named typePress Ctrl+Shift+R and then choose Replace Anonymous Type with Named Class.

How do you define anonymous type?

Essentially an anonymous type is a reference type and can be defined using the var keyword. You can have one or more properties in an anonymous type but all of them are read-only. In contrast to a C# class, an anonymous type cannot have a field or a method — it can only have properties.

What is an anonymous type in C#?

Anonymous types in C# are the types which do not have a name or you can say the creation of new types without defining them. It is introduced in C# 3.0. It is a temporary data type which is inferred based on the data that you insert in an object initializer.


2 Answers

Note, as per the comment, I'd just like to point out that I too recommend using a real type when you need to pass it around the program like this. Anonymous types should only really be used locally in a single method at a time (in my opinion), but anyway, here's the rest of my answer.


You can do it using a trick, by tricking the compiler into inferring the right type for you:

using System;  namespace ConsoleApplication4 {     class Program     {         static void Main(string[] args)         {             var a = new { Id = 1, Name = "Bob" };             TestMethod(a);              Console.Out.WriteLine("Press enter to exit...");             Console.In.ReadLine();         }          private static void TestMethod(Object x)         {             // This is a dummy value, just to get 'a' to be of the right type             var a = new { Id = 0, Name = "" };             a = Cast(a, x);             Console.Out.WriteLine(a.Id + ": " + a.Name);         }          private static T Cast<T>(T typeHolder, Object x)         {             // typeHolder above is just for compiler magic             // to infer the type to cast x to             return (T)x;         }     } } 

The trick is that inside the assembly, the same anonymous type (same properties, same order) resolves to the same type, which makes the trick above work.

private static T CastTo<T>(this Object value, T targetType) {     // targetType above is just for compiler magic     // to infer the type to cast value to     return (T)value; } 

usage:

var value = x.CastTo(a); 

But we're really pushing the limits here. Use a real type, it'll look and feel cleaner as well.

like image 55
Lasse V. Karlsen Avatar answered Sep 29 '22 21:09

Lasse V. Karlsen


Instead of casting to your custom type try using dynamic type.

Your event handler would look something like this:

private void cmdOK_Click(object sender, EventArgs e) {     dynamic option = bsOptions.Current;     if (option.Id == 1) { doSomething(); }       else { doSomethingElse(); } } 
like image 29
Marko Juvančič Avatar answered Sep 29 '22 23:09

Marko Juvančič