gsh*_*arp 49 c# anonymous-types anonymous-class
我今天遇到了以下问题,我想知道我的问题是否有解决方案.
我的想法是构建匿名类并将其用作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");
}
Run Code Online (Sandbox Code Playgroud)
到目前为止工作正常.
我遇到的问题是从BindingSource的"Current"属性中获取Id,因为我无法将其强制转换为匿名类型:
private void cmdOK_Click(object sender, EventArgs e)
{
var option = (???)bsOptions.Current;
}
Run Code Online (Sandbox Code Playgroud)
我想有没有办法找出"当前"的类型并访问"Id"属性?也许某人有一个好的解决方案......
我知道还有其他(也有更好的)方法来获取Id(反射,从ComboBox中读取值,而不是使用匿名tpyes,...)如果可以从bsOptions中获取Type,我只是很好.目前以优雅的方式.
ang*_*son 85
请注意,根据评论,我只想指出,当你需要像这样传递它时,我也建议使用真实类型.匿名类型应该一次只能在一个方法中本地使用(在我看来),但无论如何,这是我的答案的其余部分.
您可以使用技巧,通过欺骗编译器为您推断出正确的类型:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
诀窍是在程序集内部,相同的匿名类型(相同的属性,相同的顺序)解析为相同的类型,这使得上面的技巧工作.
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;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var value = x.CastTo(a);
Run Code Online (Sandbox Code Playgroud)
但我们真的在这里推动极限.使用真实的类型,它看起来也感觉更干净.
Mar*_*čič 18
而不是强制转换为自定义类型尝试使用动态类型.
您的事件处理程序看起来像这样:
private void cmdOK_Click(object sender, EventArgs e)
{
dynamic option = bsOptions.Current;
if (option.Id == 1) { doSomething(); }
else { doSomethingElse(); }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44989 次 |
| 最近记录: |