Why does char[].Cast<int> raise a cast exception? [duplicate] - c#

This question already has answers here:
Why Enumerable.Cast raises an InvalidCastException?
(2 answers)
Closed 5 years ago.
Here is the code. It's simple enough.
var text = "abcdef";
var c1 = text.Cast<int>().ToArray(); // either this one
var c2 = text.ToCharArray().Cast<int>().ToArray(); // or this one
It raises an invalid cast exception in either case. Why?
For bonus marks, what's the simplest way to do what I'm obviously trying to do, if this is not it?
So, the code I'm actually going to write it this:
var c3 = text.Select(c=>(int)c).ToArray();
Which works fine.

Look at the source code of Cast. When you use Cast you are iterating the collection as an array of object, and then it is converted to the desidered type. So the generated code (for the Cast part) for the code you post is:
foreach (object item in text)
{
yield return (int)item;
}
Of course, this will generate an exception as documented here (link provided by Rawling in the comments, thank you).
To reproduce this you can try this code (you will get the same error):
var myChar = 'c';
object myObject = myChar;
int myInt = (int)myObject; // Exception here
A possibile solution
Disclaimer: tested only with the given example and of course really slow).
You could make your own Cast method using Convert.ChangeType.
public static class IEnumerableExtensions
{
public static IEnumerable<TResult> MyCast<TResult>(this IEnumerable source)
{
var type = typeof(TResult);
foreach (var item in source)
{
yield return (TResult)Convert.ChangeType(item, type);
}
}
}
Then you can use it as you would do with Cast.
var c1 = text.MyCast<int>();

I can't find where it is documented, but LINQ's Cast uses a cast via object, essentially performing
int i = (int)(object)c;
on each character in your string.
It boxes the char, and then tries to unbox it as an int, which isn't possible.

var text = "abcdef";
var intText = text.Select(c => (int)c);
This is something you can start with to convert each char to int in a form of IEnumerable.

Related

LINQ Select with a method that returns a type - creating a new list [duplicate]

This question already has answers here:
Convert a list to a string in C#
(14 answers)
Closed 9 months ago.
I am a mere beginner and I am trying to learn a bit of LINQ. I have a list of values and I want to receive a different list based on some computation. For example, the below is often quoted in various examples across the Internet:
IEnumerable<int> squares = Enumerable.Range(1, 10).Select(x => x * x);
here the "computation" is done by simply multiplying a member of the original list by itself.
I wanted to actually use a method that returns a string and takes x as an argument.
Here is the code I wrote:
namespace mytests{
class program {
static void Main (string[] args)
{
List<string> nums = new List<string>();
nums.Add("999");
nums.Add("888");
nums.Add("777");
IEnumerable<string> strings = nums.AsEnumerable().Select(num => GetStrings(num));
Console.WriteLine(strings.ToString());
}
private static string GetStrings (string num){
if (num == "999")
return "US";
else if (num == "888")
{
return "GB";
}
else
{
return "PL";
}
}
}
}
It compiles but when debugging, the method GetStrings is never accessed and the strings object does not have any members. I was expecting it to return "US", "GB", "PL".
Any advice on what I could be doing wrong?
Thanks.
IEnumerable<string>.ToString() method does not work as you expected. Result will be
System.Collections.Generic.List`1[System.String]
If you want to see the values which are held in the collection, you should create iteration.
foreach (var i in strings)
Console.WriteLine(i);
This line does two things for you. One of them is writing the values which are held in the collection to console. The other operation is iterating the collection. During iteration, values are needed and linq will execute the necessary operation (in your case GetStrings method).
Currently your code does not use the collection values, so the code does not evaluate the values and does not trigger GetStrings method.

C# how to make it so that a function that can sort strings or ints without overloading? [duplicate]

This question already has answers here:
creating a generic sort method
(2 answers)
Closed 4 years ago.
As the title says, I had to write some code to sort either array/list of strings or integers. My OOP knowledge is really rusty since I haven't used C#/Java for a long while.
Is there a way to make it so I just need to code one function so that I don't have to overload the function
(e.g InsertSort(int [] arr) and InsertSort(string [] arr))
I heard something about using IComparable or Comparator and I took a look at the documentation of both but they seems to me that those are like more for Objects.
Thanks for any help!
Generic methods should be your friend here. Generics allow you to defer the specification of types used in method until actually used in program. You can read more on Generic here.
public T[] InsertSort<T>(T[] source)
{
// Do something
}
This can be invoked using strings/int arrays as following.
var intArray = new int[]{1,2,3};
var stringArray = new string[]{"1","2","3"};
InsertSort(intArray);
InsertSort(stringArray);
To get started, you might try something like this method.
public static IEnumerable<T> InsertSort<T>(IEnumerable<T> tmp)
{
//... Perform sorting
//... Return the sorted results as IEnumerable
}
You'll be able to send in a list or an array of the types you choose.
Usage:
List<int> listA = new List<int>();
var sortedListA = InsertSort(listA);
string[] arrA = new string[5];
var sortedArrayA = InsertSort(arrA);

Do C# closures support non-local returns? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
To explain the matter here is some Scala code:
object Scratch {
def foo: Int = {
val list = List(1, 2, 3, 4)
list.foreach { each =>
if(each > 2) {
return each
}
println(each)
}
return 5
}
def main(args : Array[String]) : Unit = {
val i = foo
println("i: " + i)
}
The code above prints this to the console:
1
2
i: 3
In particular, note that the closure used by list.foreach has a return statement, and this return statement causes foo, the caller of list.foreach, to return, interrupting the foreach enumeration and providing the actual return value for foo. This return is not declared within the foo method itself, and so is a "non-local return".
The question is now how the same thing would turn out in C#, e.g. will something else be printed to the console? The question is about non-local returns in C# from inside closures. Only if they are supported the same output would occur as in the code above.
Note: This is no speciality of Scala. Other language have this as well like Smalltalk or Kotlin, probably also Ruby and others for sure.
I wanted to try this out myself, but after downloadinng 9 GB for installing Visual Studio 2017 I was told to upgrade to Windows 10 and that was not what I wanted to do just to get this question answered.
No, C# does not support non-local returns in closures. A C# closure is a method unto itself, and does not share context (other than captured variables) with its enclosing method. When you return from within a lambda expression, you are returning from that method, i.e. the anonymous method the lambda refers to. It doesn't affect the method in which the lambda is declared, nor the method from which the lambda is invoked (if different from that in which it's declared).
I'm not that familiar with either Scala or Ruby, but it appears that Scala is more similar to Ruby than to C#. If so, I take it that non-local returns cause the calling method to return. It just happens in your example that the calling method is the same as the declaring method, but for obvious reasons it would be pretty odd for a lambda to cause the declaring method to return. I.e. the lambda might be invoked after the declaring method has already returned. There's more in-depth discussion of Ruby (and by inference, Scala) at the Stack Overflow question Is Ruby's code block same as C#'s lambda expression?.
Of course, you can still accomplish the same effect in C#. It's just that the exact syntax you're using won't do that. In .NET, the List<T> generic class has a ForEach() method, so taking your code example literally (i.e. using that built-in ForEach() method), this is the closest you can come in C#:
static void Main(string[] args)
{
var i = foo();
WriteLine($"i: {i}");
}
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
try
{
list.ForEach(each =>
{
if (each > 2)
{
throw new LocalReturnException(each);
}
WriteLine(each);
});
}
catch (LocalReturnException e)
{
return e.Value;
}
return 5;
}
class LocalReturnException : Exception
{
public int Value { get; }
public LocalReturnException(int value)
{
Value = value;
}
}
Because the List<T>.ForEach() method does not provide any mechanism to interrupt its enumeration of the source enumerable, the only way to get the method to return prematurely is to bypass the normal method-returning mechanisms by throwing an exception.
Of course, exceptions are fairly heavy-weight. There's a marginal cost just for the try/catch handler, and actually throwing and catching one is very costly. If you have a need for this idiom, it would be better to create your own enumeration method which provides for a mechanism to interrupt the enumeration and return a value. For example, create extension methods like so:
public static T? InterruptableForEach<T>(this IEnumerable<T> source, Func<T, T?> action)
where T : struct
{
foreach (T t in source)
{
T? result = action(t);
if (result != null) return result;
}
return null;
}
public static T InterruptableForEach<T>(this IEnumerable<T> source, Func<T, T> action)
where T : class
{
foreach (T t in source)
{
T result = action(t);
if (result != null) return result;
}
return null;
}
The first is needed for your example. I show two, because C# treats value types like int differently from reference types when it comes to null values, but the second isn't strictly needed here.
With the extension method, you can then do something like this:
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
var result = list.InterruptableForEach(each =>
{
if (each > 2)
{
return each;
}
WriteLine(each);
return null;
});
return result ?? 5;
}
Note that the caller needs to cooperate with the lambda and the extension method. That is, the extension method is explicitly reporting what the lambda itself returned, so that it knows whether the lambda returned prematurely and if so, what the value is.
On the one hand, this is a bit more clumsy and verbose than the Scala version. On the other hand, it's consistent with C#'s tendency toward explicitness and expressiveness, and avoidance of ambiguous situations (such as, what if the foo() method didn't return an int, but the lambda did?).
This answer shows yet another possible approach. I personally would prefer either of the above, as they both actually interrupt the enumeration, rather than just skip the main lambda body until the end of the enumeration (which could be a problem for infinite enumerations), and don't introduce the additional captured variables required by that answer. But it does work in your example.
this are my answers to your questions:
1)
You dont need to install anything for playing arround with C# and LINQ. You can simply use https://dotnetfiddle.net
2) Here is my code https://dotnetfiddle.net/3V8vBj
using System.Collections.Generic;
public class Program
{
static int foo()
{
var list = new List<int> { 1, 2, 3, 4 };
int ret = 5;
bool keepGoing = true;
list.ForEach(each =>
{
if (!keepGoing)
return;
if (each>2)
{
ret=each;
keepGoing = false;
return;
}
System.Console.WriteLine(each);
});
return ret;
}
public static void Main(string[] args)
{
var i = foo();
System.Console.WriteLine("i: " + i);
}
}
3) When you using LINQ Foreach you can not simply break it for return, since it is a delegate function. So I had to implement keepGoing.
4) The nested delegate function can not return a value, so I have to use "ret" for setting the return inside the LINQ Foreach.
I hope this answers your question, but I am not really sure that I understand it right.

How to check the type of an Object (including boxed scalar) in WinRT + C++/CX

I have a C# function that returns an arbitrary Object (which can be a string, a dictionary, or any other class, including boxed numbers) e.g.
public static Object foo() {
return 3.14;
}
When called from C++/CX on WinRT how can I know check the type of the returned object? I don't understand why this doesn't work:
if (result->GetType() == String::typeid)
if (result->GetType() == double::typeid)
if (result->GetType()->Equals(double::typeid))
This does work for "real" objects:
auto temp = dynamic_cast<String^>(result);
if (temp) {
...
}
But I can't figure out how to handle the boxed number case since dynamic_cast<Double>(result) is not possible.
PS: I saw this similar question but it doesn't cover the boxed number case.
After quite a bit of Googling I found this solution but I have no idea if that's proper:
Object^ result = ...
if (dynamic_cast<IBox<double>^>(result)) {
auto value = safe_cast<double>(result);
...
}
auto string = dynamic_cast<String^>(result);
if (string) {
auto value = _PlatformStringToString(string);
...
}

How to mimic a lambda expression returning a value [duplicate]

This question already has answers here:
Func<T> with out parameter
(4 answers)
Closed 7 years ago.
Ignoring the irrelevant parts - I have a requirement to use a delegate with no arguments and no return value, but get a value from it.
The current solution is to use a lambda expression and a variable that's declared before it.
string result;
RequiredMethod(() => { result = "the result"; });// Gets the result from a 2nd thread.
//use result
Is there a way to do this without using a lambda expression? I expect there should be, but can't come up with it.
Yes of course there is:
public class ValueHolder
{
public string Value { get; private set; }
public void AssignValue()
{
this.Value = "the result";
}
}
// usage
var vh = new ValueHolder();
RequiredMethod(vh.AssignValue);
// access value
vh.Value
The code you provided told me that you try to access values from another thread. Please keep in mind that you should not access vh.Value until AssignValue has been called. You need to add some other code to sync these operations (but your lambda has exactly the same problem).
also the question is why do you have to use a delegate. If it's about getting the value you could even implement it in a way like this
string someString;
RequiredMethod(ref someString);
Of course this would change the signature of the RequiredMethod (and the question becomes why you couldn't return a value in the first place.).
You could even write an overload of the 2nd using your lamdba expression.
void RequireMethod(string ref variable) {
RequireMethod(() => { variable = "the result";});
}

Categories