Sunday, 15 February 2015

c# 4.0 - C# explicit cast - from collection of KeyValuerPair to Dictionary -



c# 4.0 - C# explicit cast - from collection of KeyValuerPair to Dictionary -

i have list of keyvaluepairs. utilize todictionary.

however noted error message (shown below) has explicit cast, implies can cast list dictionary<...>. how can this?

cannot implicitly convert type 'system.linq.iorderedenumerable<system.collections.generic.keyvaluepair<int,string>>' 'system.collections.generic.dictionary<int, string>'. explicit conversion exists (are missing cast?)

sample code:

dictionary<int, string> d = new dictionary<int, string>() { {3, "c"}, {2, "b"}, {1, "a"}, }; var s = d.orderby(i => i.value); d = s;

implies can cast list dictionary

well, implies cast valid @ compile-time. doesn't mean work @ execution time.

it's possible code work:

iorderedenumerable<keyvaluepair<string, string>> pairs = getpairs(); dictionary<string, string> dictionary = (dictionary<string, string>) pairs;

... if value returned getpairs() class derived dictionary<,> implemented iorderedenumerable<keyvaluepair<string, string>>. it's unlikely that's actually case in normal code. compiler can't stop trying, won't end well. (in particular, if code in question , standard linq objects, fail @ execution time.)

you should stick todictionary... although should aware you'll lose ordering, there's no point in ordering start with.

to show code in question:

dictionary<int, string> d = new dictionary<int, string>() { {3, "c"}, {2, "b"}, {1, "a"}, }; var s = d.orderby(i => i.value); d = (dictionary<int, string>) s;

that compiles, fails @ execution time predicted:

unhandled exception: system.invalidcastexception: unable cast object of type 'system.linq.orderedenumerable`2[system.collections.generic.keyvaluepair`2[system.int32,system.string],system.string]' type 'system.collections.generic.dictionary`2[system.int32,system.string]'. @ test.main()

as bit of background, can always cast interface type non-sealed class ("target"), if type doesn't implement interface, because it's possible class derived "target" implement interface.

from section 6.2.4 of c# 5 specification:

the explicit reference conversions are:

... from class-type s interface-type t, provided s not sealed , provided s not implement t. ...

(the case s does implement t covered implicit reference conversions.)

if seek implicitly convert value , there's no implicit conversion available, there's explicit conversion available, compiler give warning in question. means can prepare compiler-error cast, need aware of possibility of failing @ execution time.

here's example:

using system; class test { static void main() { iformattable x = getobject(); } static object getobject() { homecoming datetime.now.second >= 30 ? new object() : 100; } }

error message:

test.cs(7,26): error cs0266: cannot implicitly convert type 'object' 'system.iformattable'. explicit conversion exists (are missing cast?)

so can add together cast:

iformattable x = (iformattable) getobject();

at point, code work half time - other half, it'll throw exception.

c#-4.0 .net-4.5

No comments:

Post a Comment