1

I want to convert a string into an array of bytes. When I try this by use of the Cast-function of LINQ, I get a 'System.InvalidCastException'. Why? Here is, what I tried:

var x = "hallo";
var works = x.Select(c=>(byte)c).ToArray();
var doesNotWork = x.Cast<byte>().ToArray();
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Harald Hoyer
  • 515
  • 4
  • 14

4 Answers4

5

Enumerable.Cast only performs unboxing and reference conversions. It does not perform other conversions such as the built-in value type ones and user-defined conversions.

Before .NET 3.5 SP1 it actually did perform rather more conversions for you. I'm sure the person who performed the code review blogged about it, but I can never remember who it was. (I keep thinking it was Eric Lippert, but it wasn't.) I'll look it up.

One thing I'll say is that this could be better documented.

As it happens, this is the first puzzler in Bill Wagner's recent video.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    It's here: http://blogs.msdn.com/b/ed_maurer/archive/2008/02/16/breaking-change-in-linq-queries-using-explicitly-typed-range-variables.aspx, and was pointed out in this previous answer: http://stackoverflow.com/questions/445471/puzzling-enumerable-cast-invalidcastexception/445497#445497 – jason Aug 11 '11 at 19:11
  • @Jason: Thanks - I don't think that's the blog post I was thinking of, but it's similar :) – Jon Skeet Aug 11 '11 at 19:14
  • I, unfortunately, did the code review that allowed the bad code to get into the world. Ed blogged about it. – Eric Lippert Aug 15 '11 at 12:17
  • 2
    @Eric: Ah, in that case maybe it was a comment in an email or something like that. Welcome back from holiday, btw. – Jon Skeet Aug 15 '11 at 12:21
4

I guess I have to ask why you would want to perform a cast of a string value into a byte array without using an Encoding?

string value = "Some Value";
byte[] myBytes = System.Text.Encoding.UTF8.GetBytes(value);
Jay
  • 6,224
  • 4
  • 20
  • 23
  • I am uncertain, which Endoding I have to use. Why UTF8? – Harald Hoyer Aug 11 '11 at 19:30
  • 1
    UTF-8 is just one I picked. You can encode using any page, but .Net provides shortcuts for ASCII and UTF flavors. UTF-8 is also the most common encoding for Latin based languages. – Jay Aug 11 '11 at 19:31
0

try this:

var works = x.ToArray().Select(c => (byte)c).ToArray();

chris.house.00
  • 3,273
  • 1
  • 27
  • 36
  • 2
    Why would you call `ToArray` first? That's *just* added overhead on top of the original already-working code. – Jon Skeet Aug 11 '11 at 19:15
0

From Anders Hejlsberg:

Right, due to a bug (should I say unintended feature?) in the RTM version of .NET 3.5 the Cast method works for some conversions, but with unexpected semantics. For example, floating-point to integral conversions use bankers rounding, whereas regular C# casts round toward zero. Also, the Cast method was rather slow and inefficient in .NET 3.5 RTM. All of this was fixed in SP1, and Cast now only supports reference and boxing conversions as originally intended--and does so efficiently.

I think the 3.5sp1 change to Enumerable.Cast is to make it work with .Net's notion of casting, which is different than the capabilities reached using c#'s casting syntax (specifically: conversions). This makes sense as .Cast is a .net framework thing and not a c# thing.

Amy B
  • 108,202
  • 21
  • 135
  • 185