我在这里疯了。这可能是因为我错过了一些规则,但如果是这样,请告诉我。
我正在尝试创建一个Dictionary
,其中包含一个用于键的字符串和一个匿名对象作为值。或者,实际上我不只是尝试,我正在做。
但是当我想改变对象中的特定参数时,就会出错。
我这样宣布字典:
var areas = new Dictionary<string, object>
{
{"Key1", new {name = "Name1", today = 0, all = 0}},
{"Key2", new {name = "Name2", today = 0, all = 0}},
...
}
然后我假设我可以这样做:
foreach (var area in areas.Keys.ToArray())
{
var areaname = areas[area].name;
}
但Visual Studio不同意,并拒绝编译。但是,如果我写这篇文章,一切都按照我的想法运作 - 但这并没有真正帮助我,这只会让我更加沮丧。
var areaname = new
{
name = "Nametest", today = 0, all = 0
};
var testname = areaname.name;
我做错了什么?为什么它不适合我?这样做根本不可能吗?
感谢您的所有答案,他们肯定清理了一下! 我想我可能会把类型 object 与C#中的对象的想法混淆起来,而不是沮丧。我将重新思考整个设计业务,并可能做一些完全不同的事情,而不是使用邪恶或肮脏的解决方案。虽然有趣,但我认为我与C#的关系还没有发展到那么远!
答案 0 :(得分:24)
这不起作用,因为您已将字典声明为Dictionary<string, object>
。
您可以尝试Dictionary<string, dynamic>
。
答案 1 :(得分:10)
这不起作用,因为您已将字典声明为Dictionary<string, object>
。
C#在后台为您创建一个具有这些属性的新类型(您无法访问)(此处称为匿名类型)。您可以直接使用它的唯一时间是它仍为var
类型 - 只要您将其添加到该字典,它就会转换为object
,因此您无法再访问这些属性。
选项1
您可以尝试Dictionary<string, dynamic>
。 Dynamic将能够访问这些属性 - 但这仅在C#/ .Net 4.0
选项2
您可以使用称为演示的技术(通过示例演员)获取类型。这不是一个记录的功能,是浪费,而且有点像黑客。 This is a horrible evil trick - 特别是因为它不适用于程序集。
public static T Demonstrate<T>(this T demonstration, object value)
{
return (T)value;
}
然后您可以访问原始属性,如下所示:
var area = new { name = "", today = 0, all = 0 }.Demonstrate(areas[name]);
var areaName = value.name;
选项3 这是老实说最好的方法
写一堂课。如果您喜欢C#编译器为您完成所有Equals
,GetHashCode
和ToString
工作的事实,您可以使用类似ILSpy的内容来获取原始代码。因此:
class AreaInfo
{
public string Name { get; set; }
public int Total { get; set; }
public int All { get; set; }
public override bool Equals(object obj)
{
var ai = obj as AreaInfo;
if (object.ReferenceEquals(ai, null))
return false;
return Name == ai.Name && Total == ai.Total && All == ai.All;
}
public override int GetHashCode()
{
var hc = 0;
if (Name != null)
hc = Name.GetHashCode();
hc = unchecked((hc * 7) ^ Total);
hc = unchecked((hc * 21) ^ All);
return hc;
}
public override string ToString()
{
return string.Format("{{ Name = {0}, Total = {1}, All = {2} }}", Name, Total, All);
}
}
更正字典:
var areas = new Dictionary<string, AreaInfo>
{
{"Key1", new AreaInfo() {Name = "Name1", Today = 0, All = 0}},
{"Key2", new AreaInfo() {Name = "Name2", Today = 0, All = 0}},
...
};
现在事情会按照你期望的方式发挥作用。
答案 2 :(得分:9)
这不会编译,因为字典中的值的类型为object
,而object
不包含属性name
。
如果您使用的是.NET 4,则可以将类型从object
更改为dynamic
。
话虽如此,我强烈反对这一设计决定。你真的应该为此创建一个类。
答案 3 :(得分:6)
要使Dictionary的值具有正确的匿名类型,请执行以下操作:
var areas=new[] {
new {Key="Key1", Value=new {name="Name1", today=0, all=0}},
new {Key="Key2", Value=new {name="Name2", today=0, all=0}},
}.ToDictionary(kv => kv.Key, kv => kv.Value);
然后您的代码将按预期工作:
foreach(var area in areas.Keys.ToArray()) {
var areaname=areas[area].name;
}
答案 4 :(得分:1)
匿名类型的详细信息在创建它们的程序集之外是不可移植的,并且除了方法之外 † >它们是在。中创建的。您应该使用onymous类型,或者dynamic
如果您想采用动态方法。
†这里有一个邪恶的伎俩,我故意不提,因为它是邪恶的。