C# 转换为匿名类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1409734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cast to Anonymous Type
提问by gsharp
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:
我的想法是构建匿名类并将其用作 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:
我遇到的问题是从 BindingSource 的“Current”属性中获取 Id,因为我无法将其转换回匿名类型:
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...
我想没有办法找出“当前”的类型并访问“Id”属性吗?也许有人有一个很好的解决方案......
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.
我知道还有其他(也是更好的)方法来获取 Id(反射,从 ComboBox 读取值,而不是使用匿名 tpyes,...)我只是好奇是否可以从 bsOptions 中获取类型。以优雅的方式当前。
采纳答案by Lasse V. Karlsen
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.
但我们真的在挑战这里的极限。使用真正的类型,它的外观和感觉也会更干净。
回答by Vilx-
回答by Philippe Leybaert
In C# 3.0, this is not possible. You'll have to wait for C# 4.0, which allows accessing properties at runtime using "dynamic" variables.
在 C# 3.0 中,这是不可能的。您将不得不等待 C# 4.0,它允许在运行时使用“动态”变量访问属性。
回答by manji
you can try this:
你可以试试这个:
private void cmdOK_Click(object sender, EventArgs e)
{
var option = Cast(bsOptions.Current, new { Id = 0, Option = "", Description = "" });
}
see: Can't return anonymous type from method? Really?
请参阅:无法从方法返回匿名类型?真的吗?
回答by Guillaume86
You can also declare an array of anonymous Types directly with that syntax:
您还可以直接使用该语法声明一个匿名类型数组:
var data = new [] {
new {Id = 0, Name = "Foo"},
new {Id = 42, Name = "Bar"},
};
回答by Tono Nam
public class MyExtensMethods{
public static T GetPropertyValue<T>(this Object obj, string property)
{
return (T)obj.GetType().GetProperty(property).GetValue(obj, null);
}
}
class SomeClass
{
public int ID{get;set;}
public int FullName{get;set;}
}
// casts obj to type SomeClass
public SomeClass CastToSomeClass(object obj)
{
return new SomeClass()
{
ID = obj.GetPropertyValue<int>("Id"),
FullName = obj.GetPropertyValue<string>("LastName") + ", " + obj.GetPropertyValue<string>("FirstName")
};
}
.... then to cast you will do:
....然后投你会做:
var a = new { Id = 1, FirstName = "Bob", LastName="Nam" };
SomeClass myNewVar = CastToSomeClass(a);
回答by Marko Juvan?i?
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(); }
}