I have the following dictionary in a method:
我有以下的字典的方法:
var nmDict = xelem.Descendants(plantNS + "Month").ToDictionary(
k => new Tuple<int, int, string>(int.Parse(k.Ancestors(plantNS + "Year").First().Attribute("Year").Value), Int32.Parse(k.Attribute("Month1").Value), k.Ancestors(plantNS + "Report").First().Attribute("Location").Value.ToString()),
v => {
var detail = v.Descendants(plantNS + "Details").First();
return
new
{
BaseHours = detail.Attribute("BaseHours").Value,
OvertimeHours = detail.Attribute("OvertimeHours").Value
};
});
I need to return nmDict. The problem is that I cannot figure out how to label my method signature. I have tried the following:
我需要返回nmDict。问题是我不知道如何标记我的方法签名。我试过以下方法:
protected IDictionary<XElement, XElement> OvertimereportData(HarvestTargetTimeRangeUTC ranges)
The above gives me this error:
上面给了我这个错误:
Cannot implicitly convert type System.Collections.Generic.Dictionary<System.Tuple<int,int,string>,AnonymousType#1>' to 'System.Collections.Generic.IDictionary<System.Xml.Linq.XElement,System.Xml.Linq.XElement>'. An explicit conversion exists (are you missing a cast?)
protected IDictionary<Tuple, XElement> OvertimereportData(HarvestTargetTimeRangeUTC ranges)
gives me this error:
给了我这个错误:
'System.Tuple': static types cannot be used as type arguments
I do not know what to do.
我不知道该怎么办。
3 个解决方案
#1
1
When you call the ToDictionary
method, the resulting dictionary's type has little to do with the type of elements in your source sequence. It's defined entirely by the data types returned by the key and value expressions you supply to the call. For example, if you were to call:
当您调用ToDictionary方法时,结果字典的类型与源序列中的元素类型几乎没有关系。它完全由您提供给调用的键和值表达式返回的数据类型定义。例如,如果你打电话:
xelem.Descendants(plantNS + "Month").ToDictionary(
k => int.Parse(k.Attribute("Year").Value),
v => k.Attribute("Year).Value
);
You would get an IDictionary<int, string>
because that's what your two expressions returned. To return that from a method, you just need to construct the correct type, based on your expressions.
你会得到一个IDictionary
Your first one is easy:
第一个很简单:
k => new Tuple<int, int, string>(...)
The second one, though, is going to be a problem. The values in your dictionary are of an anonymous type: you return a new { }
without specifying a concrete type name for that value. In general, that is going to make it impossible for you to use that dictionary as a return value or parameter. (It can be done, using some very strange-looking generic techniques, but I wouldn't recommend it.)
然而,第二个问题将是一个问题。字典中的值是匿名类型:返回一个新的{},但不指定该值的具体类型名。一般来说,这将使您无法使用该字典作为返回值或参数。(可以使用一些看起来很奇怪的通用技术完成,但我不推荐它。)
The first thing you'll need to do, then, is make a concrete type to hold your values, e.g.
你要做的第一件事,就是做一个具体的类型来保持你的价值观。
public class HoursContainer
{
public string BaseHours { get; set; }
public string OvertimeHouse { get; set; }
}
and change your Linq query appropriately:
并适当地更改Linq查询:
var detail = v.Descendants(plantNS + "Details").First();
return new HoursContainer
{
BaseHours = detail.Attribute("BaseHours").Value,
OvertimeHours = detail.Attribute("OvertimeHours").Value
};
Once you've done this, your dictionary will have a concrete type based on the types of things you specified when you created it:
一旦你这样做了,你的字典将会有一个具体的类型,基于你在创建它时指定的类型:
IDictionary<Tuple<int, int, string>, HoursContainer>
IDictionary <元组< int,int,字符串> ,HoursContainer >
(Note: You could also just use another Tuple<int, int>
or whatever here, if you wanted, but the resulting generic type would get unwieldy very fast.)
(注意:如果需要,也可以使用另一个Tuple
#2
3
The short answer: You can't return anonymous types from a function.
简短的回答是:不能从函数中返回匿名类型。
The long answer: Your dictionary's value type is anonymous {BaseHours, OvertimeHours}
which cannot be returned from a function or passed as an argument (except as an object, but that does nobody any good unless you go through the hassle of reflecting into it). Either define a class/struct with BaseHours
and OvertimeHours
in it, or use a tuple. The former is probably slightly better because you can keep the names BaseHours
and OvertimeHours
; with a tuple you just get Value1
and Value2
.
答案很长:您的字典的值类型是匿名的{BaseHours, OvertimeHours},它不能从函数中返回,也不能作为参数传递(除了作为对象外,但这没有任何好处,除非您仔细考虑它)。要么用BaseHours和OvertimeHours定义一个类/结构,要么使用tuple。前者可能稍好一些,因为您可以保持名称为BaseHours和OvertimeHours;对于一个元组,你只需要获取Value1和Value2。
#3
2
If you are using C# 4.0 than you can return the anonymous via dynamic type. So your method signature would look like this
如果您正在使用c# 4.0,那么您可以通过动态类型返回匿名。你的方法签名是这样的
protected IDictionary<Tuple<int,int,string>, dynamic> OvertimereportData(HarvestTargetTimeRangeUTC ranges)
And through the dynamic object you can find the properties at run time.
通过动态对象可以在运行时找到属性。
Hope this will help you.
希望这对你有帮助。
#1
1
When you call the ToDictionary
method, the resulting dictionary's type has little to do with the type of elements in your source sequence. It's defined entirely by the data types returned by the key and value expressions you supply to the call. For example, if you were to call:
当您调用ToDictionary方法时,结果字典的类型与源序列中的元素类型几乎没有关系。它完全由您提供给调用的键和值表达式返回的数据类型定义。例如,如果你打电话:
xelem.Descendants(plantNS + "Month").ToDictionary(
k => int.Parse(k.Attribute("Year").Value),
v => k.Attribute("Year).Value
);
You would get an IDictionary<int, string>
because that's what your two expressions returned. To return that from a method, you just need to construct the correct type, based on your expressions.
你会得到一个IDictionary
Your first one is easy:
第一个很简单:
k => new Tuple<int, int, string>(...)
The second one, though, is going to be a problem. The values in your dictionary are of an anonymous type: you return a new { }
without specifying a concrete type name for that value. In general, that is going to make it impossible for you to use that dictionary as a return value or parameter. (It can be done, using some very strange-looking generic techniques, but I wouldn't recommend it.)
然而,第二个问题将是一个问题。字典中的值是匿名类型:返回一个新的{},但不指定该值的具体类型名。一般来说,这将使您无法使用该字典作为返回值或参数。(可以使用一些看起来很奇怪的通用技术完成,但我不推荐它。)
The first thing you'll need to do, then, is make a concrete type to hold your values, e.g.
你要做的第一件事,就是做一个具体的类型来保持你的价值观。
public class HoursContainer
{
public string BaseHours { get; set; }
public string OvertimeHouse { get; set; }
}
and change your Linq query appropriately:
并适当地更改Linq查询:
var detail = v.Descendants(plantNS + "Details").First();
return new HoursContainer
{
BaseHours = detail.Attribute("BaseHours").Value,
OvertimeHours = detail.Attribute("OvertimeHours").Value
};
Once you've done this, your dictionary will have a concrete type based on the types of things you specified when you created it:
一旦你这样做了,你的字典将会有一个具体的类型,基于你在创建它时指定的类型:
IDictionary<Tuple<int, int, string>, HoursContainer>
IDictionary <元组< int,int,字符串> ,HoursContainer >
(Note: You could also just use another Tuple<int, int>
or whatever here, if you wanted, but the resulting generic type would get unwieldy very fast.)
(注意:如果需要,也可以使用另一个Tuple
#2
3
The short answer: You can't return anonymous types from a function.
简短的回答是:不能从函数中返回匿名类型。
The long answer: Your dictionary's value type is anonymous {BaseHours, OvertimeHours}
which cannot be returned from a function or passed as an argument (except as an object, but that does nobody any good unless you go through the hassle of reflecting into it). Either define a class/struct with BaseHours
and OvertimeHours
in it, or use a tuple. The former is probably slightly better because you can keep the names BaseHours
and OvertimeHours
; with a tuple you just get Value1
and Value2
.
答案很长:您的字典的值类型是匿名的{BaseHours, OvertimeHours},它不能从函数中返回,也不能作为参数传递(除了作为对象外,但这没有任何好处,除非您仔细考虑它)。要么用BaseHours和OvertimeHours定义一个类/结构,要么使用tuple。前者可能稍好一些,因为您可以保持名称为BaseHours和OvertimeHours;对于一个元组,你只需要获取Value1和Value2。
#3
2
If you are using C# 4.0 than you can return the anonymous via dynamic type. So your method signature would look like this
如果您正在使用c# 4.0,那么您可以通过动态类型返回匿名。你的方法签名是这样的
protected IDictionary<Tuple<int,int,string>, dynamic> OvertimereportData(HarvestTargetTimeRangeUTC ranges)
And through the dynamic object you can find the properties at run time.
通过动态对象可以在运行时找到属性。
Hope this will help you.
希望这对你有帮助。