I am having a problem with C# giving the "Use of unassigned local variable" compile error. What am I missing?
// returns generic result of a function with error message
// why the function failed
public class Result
{
public bool isSuccess = true;
public string errorMessage = string.Empty;
public static implicit operator bool(Result r)
{
return r.isSuccess;
}
public static Result operator &(Result a, Result b)
{
return !a.isSuccess ? a : b;
}
public static Result operator |(Result a, Result b)
{
if (a.isSuccess)
{
return a;
}
if (b.isSuccess)
{
return b;
}
return new Result
{
isSuccess = false,
errorMessage = $"{a.errorMessage}\nOut{b.errorMessage}"
};
}
public static bool operator false(Result a)
{
return !a.isSuccess;
}
public static bool operator true(Result a)
{
return a.isSuccess;
}
}
static Result Func1(int nIn, out int nOut)
{
nOut = nIn + 1;
return new Result();
}
private static void Main(string[] args)
{
var resultA =
Func1(0, out var a1) &&
Func1(a1, out var a2); // compiles fine
var resultB =
Func1(0, out var b1) &&
Func1(b1, out var b2) &&
Func1(b2, out var b3); // Use of unassigned local variable 'b2'
}
I think this may be a bug in the compiler - I'd personally expect b2 to be definitely assigned there. The spec for definite assignment is pretty hairy though, so I'm not going to try to prove it one way or another right now. It's possible that the rules aren't "clever" enough to work out that the only way that (x && y) is true is if both x and y are evaluated, and so in (x && y) && z, z should be able to rely on both x and y having been evaluated.
However, it's fairly easy to work around, just with an extra pair of parentheses:
var resultB =
Func1(0, out var b1) &&
(Func1(b1, out var b2) && Func1(b2, out var b3));
Related
I am a little befuzzled around operator overloading in C#.NET
Please inspect the following example
public enum TestActionResult
{
NoResult,
Fail,
Pass,
Exception
}
TestActionResult result = DetailsScreen.Text.Contains("YOUR DETAILS", StringComparison.OrdinalIgnoreCase) && DetailsScreen.Enabled && DetailsScreen.Displayed;
What I would like to happen:
I want to automatically convert a boolean value into a TestActionResult.
So if the boolean value on the right of my result object is true then I would like TestActionResult to infer a Pass or Fail if False.
I know you can do operator overloading in C# and I am quite sure its possible but I am not familiar with how that would work.
I did have a crack at this but it turns out that was the wrong xD
public static TestActionResult operator == (bool b1, bool b2)
{
if(b1 && b2)
{
return TestActionResult.Pass;
}
return TestActionResult.Fail;
}
public static TestActionResult operator !=(bool b1, bool b2)
{
if(!(b1 && b2))
{
return TestActionResult.Pass;
}
return TestActionResult.Fail;
}
Any help would be massively appreciated
I know I can use the Ternary operand however to me it often bloats the lines of code and I would like this to be in a sleeker format
e.g.
result = !bodyElement.GetAttribute("class").Contains("popup-visible") ? TestActionResult.Pass : TestActionResult.Fail;
This is just too long and if I could reduce it with an operator overload I would really appreciate the input
You can't do operator overloading with enums in C#. You could hold this enum as property in a class or struct which is implicitly convertible to bool and vice-versa:
public enum ActionResult
{
NoResult,
Fail,
Pass,
Exception
}
public struct TestActionResult
{
public TestActionResult(ActionResult initialResult)
{
Result = initialResult;
}
private static readonly TestActionResult PassResult = new TestActionResult { Result = ActionResult.Pass };
private static readonly TestActionResult FailResult = new TestActionResult { Result = ActionResult.Fail };
public ActionResult Result { get; private set; }
public static implicit operator TestActionResult(bool b)
{
return b ? PassResult : FailResult;
}
public static implicit operator bool(TestActionResult tar)
{
return tar.Result == ActionResult.Pass;
}
}
If you override operator for 2 bools. These operators apply to your project...
I think this makes the simplest.
TestActionResult result = DetailsScreen.Text.Contains("YOUR DETAILS", StringComparison.OrdinalIgnoreCase) && DetailsScreen.Enabled && DetailsScreen.Displayed
? TestActionResult.Pass
: TestActionResult.Failed;
Or an extension for the bool
public static bool ToEnum(this bool value) {
return value ? TestActionResult.Pass : TestActionResult.Failed;
}
then
TestActionResult result =(DetailsScreen.Text.Contains("YOUR DETAILS", StringComparison.OrdinalIgnoreCase) && DetailsScreen.Enabled && DetailsScreen.Displayed)
.ToEnum();
Is there a way in C# to use maxvalue when an int would be out of range.
For my purposes I can't use a long.
Example
int a = 842673832;
int b = 2131231321;
int t = a * b;
//if t out of range, t = Int32.MinValue;
You would need to test it before hand or create a very special kind of integer (like CheckedInt in the link).
Option A
To test it before hand, you need a data type which can handle big integer value (say, long):
long t = (long)a * b;
int r = t > int.MaxValue ? int.MaxValue : t < int.MinValue ? : int.MinValue : (int)t;
Option B
To use the special kind of integer, you may need to overload the basic operators too.
In the example in the link, the exception is thrown, but you could change the exception into implementing int.MaxValue or int.MinValue, something like this:
public struct CheckedInt {
private int Value { get; set; }
public CheckedInt(int value)
: this() {
Value = value;
}
public static implicit operator CheckedInt(int me) {
return new CheckedInt(me);
}
public static CheckedInt operator +(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value + (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value + rhs.Value); //note that direct lhs+rhs will cause StackOverflow
}
public static CheckedInt operator -(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value - (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value - rhs.Value); //note that direct lhs-rhs will cause StackOverflow
}
public static CheckedInt operator *(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value * (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value * rhs.Value); //note that direct lhs*rhs will cause StackOverflow
}
public static CheckedInt operator /(CheckedInt lhs, CheckedInt rhs) {
double testResult = (double)lhs.Value / (double)rhs.Value;
if (testResult > int.MaxValue)
return int.MaxValue;
if (testResult < int.MinValue)
return int.MinValue;
return new CheckedInt(lhs.Value / rhs.Value); //note that direct lhs-rhs will cause StackOverflow
}
//Add any other overload that you want
public override string ToString() { //example
return Value.ToString();
}
public bool Equals(CheckedInt otherInt) { //example
return Value == otherInt.Value;
}
}
You can try this by enabling overflow checking
int t;
try
{
int a = 842673832;
int b = 2131231321;
t = checked(a * b);
}
catch (System.OverflowException e)
{
t = Int32.MaxValue;
}
If you want t to be an int and not a larger type like Ian's answer, you can catch at OverflowException and set t to MaxValue. Make sure to wrap the section in a checked keyword to allow overflow checking.
int t = 0;
checked {
try
{
int a = 842673832;
int b = 2131231321;
t = a * b;
}
catch (OverflowException)
{
t = int.MaxValue;
}
}
I have a huge array that contains reference type elements, and I want to create a lot of other arrays that essentially just point to specific parts of that one big array.
In other words, I want to create "indexers" or "pointers with lengths".
In C++ it's easy to do so using pointers and for each pointer assign a length, for example create a struct which contains a pointer with a length.
How can I achieve this in C#/.NET?
The whole point is to avoid copying anything, I just want pointers to specific parts in an array that already exists in memory.
Any ideas?
Jon's suggestion of using ArraySegment<T> is likely what you want. If however you are wanting to represent a pointer to the interior of an array, the way you can in C++, here's some code for that. No warranty is expressed or implied, use at your own risk.
This code does not track the "length" of the interior pointer in any way, but it is quite easy to add that feature if you want.
internal struct ArrayPtr<T>
{
public static ArrayPtr<T> Null { get { return default(ArrayPtr<T>); } }
private readonly T[] source;
private readonly int index;
private ArrayPtr(ArrayPtr<T> old, int delta)
{
this.source = old.source;
this.index = old.index + delta;
Debug.Assert(index >= 0);
Debug.Assert(index == 0 || this.source != null && index < this.source.Length);
}
public ArrayPtr(T[] source)
{
this.source = source;
index = 0;
}
public bool IsNull()
{
return this.source == null;
}
public static bool operator <(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index < b.index;
}
public static bool operator >(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index > b.index;
}
public static bool operator <=(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index <= b.index;
}
public static bool operator >=(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index >= b.index;
}
public static int operator -(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index - b.index;
}
public static ArrayPtr<T> operator +(ArrayPtr<T> a, int count)
{
return new ArrayPtr<T>(a, +count);
}
public static ArrayPtr<T> operator -(ArrayPtr<T> a, int count)
{
return new ArrayPtr<T>(a, -count);
}
public static ArrayPtr<T> operator ++(ArrayPtr<T> a)
{
return a + 1;
}
public static ArrayPtr<T> operator --(ArrayPtr<T> a)
{
return a - 1;
}
public static implicit operator ArrayPtr<T>(T[] x)
{
return new ArrayPtr<T>(x);
}
public static bool operator ==(ArrayPtr<T> x, ArrayPtr<T> y)
{
return x.source == y.source && x.index == y.index;
}
public static bool operator !=(ArrayPtr<T> x, ArrayPtr<T> y)
{
return !(x == y);
}
public override bool Equals(object x)
{
if (x == null) return this.source == null;
var ptr = x as ArrayPtr<T>?;
if (!ptr.HasValue) return false;
return this == ptr.Value;
}
public override int GetHashCode()
{
unchecked
{
int hash = this.source == null ? 0 : this.source.GetHashCode();
return hash + this.index;
}
}
public T this[int index]
{
get { return source[index + this.index]; }
set { source[index + this.index] = value; }
}
}
Now we can do stuff like:
double[] arr = new double[10];
var p0 = (ArrayPtr<double>)arr;
var p5 = p0 + 5;
p5[0] = 123.4; // sets arr[5] to 123.4
var p7 = p0 + 7;
int diff = p7 - p5; // 2
It sounds like you're looking for something like ArraySegment<T>. Contrary to my earlier thoughts, it does have an indexer and implement IEnumerable<T> etc - it's just done with explicit interfaces.
Sample code:
using System;
using System.Collections.Generic;
static class Test
{
static void Main()
{
string[] original = { "The", "quick", "brown", "fox", "jumped", "over",
"the", "lazy", "dog" };
IList<string> segment = new ArraySegment<string>(original, 3, 4);
Console.WriteLine(segment[2]); // over
foreach (var word in segment)
{
Console.WriteLine(word); // fox jumped over the
}
}
}
EDIT: As noted in comments, ArraySegment<T> is only really "fully functional" in .NET 4.5. The .NET 4 version doesn't implement any interfaces.
You could use LINQ:
yourArray.Skip(startIndex).Take(numberToTake)
The query is lazily evaluated.
(how) can I Inherit from Boolean?
(Or make my class comparable to Boolean with '=' Operator)
class MyClass : Boolean
{
public MyClass()
{
this = true;
}
}
class Program
{
public Program()
{
MyClass myClass = new MyClass();
if(myClass == true)
//do something...
else
//do something else...
}
}
You can't. System.Boolean is a struct, and you can't derive from structs.
Now, why do you want to do so, exactly? What's the bigger purpose?
You could include an implicit conversion operator from your class to bool, but personally I wouldn't. I would almost always prefer to expose a property, so you'd write:
if (myValue.MyProperty)
... I think that keeps things clear. But if you could give us more of the real context, we may be able to give more concrete advice.
Simple example:
public class MyClass {
private bool isTrue = true;
public static bool operator ==(MyClass a, bool b)
{
if (a == null)
{
return false;
}
return a.isTrue == b;
}
public static bool operator !=(MyClass a, bool b)
{
return !(a == b);
}
}
somewhere in code you can compare your object with boolean value:
MyClass a = new MyClass();
if ( a == true ) { // it compares with a.isTrue property as defined in == operator overloading method
// ...
}
You can use an implicit conversion operator to have this code:
class MyClass {
public bool Value { get; set; }
public MyClass() {
Value = true;
}
public static implicit operator bool(MyClass m) {
return m != null && m.Value;
}
}
class Program {
public static void Main() {
var myClass = new MyClass();
if (myClass) { // MyClass can be treated like a Boolean
Console.WriteLine("myClass is true");
}
else {
Console.WriteLine("myClass is false");
}
}
}
It can be used as above:
if (myClass) ...
Or like this:
if (myClass == true) ...
while your example wouldnt work, you can do something similar for your own classes to test if one equals the values of another.
http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx
public static bool operator ==(ThreeDPoint a, ThreeDPoint b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return a.x == b.x && a.y == b.y && a.z == b.z;
}
public static bool operator !=(ThreeDPoint a, ThreeDPoint b)
{
return !(a == b);
}
You can ("or make my class comparable..."), by overriding the == operator. I presume Jon Skeet overlooked that part of the question.
If you want to be able to use your value in 'if' statements, define operator true and operator false (along with the & and | operators if you want to use && and ||.) (VB equivalents)
To answer more, I would have to know what you're trying to do (in other words, why not just use bool directly?)
I got frustated with my other question. So i wrote up this example.
In C the below is true. See demo
int main()
{
printf("%d", 1 && 2);
return 0;
}
Output:
1
In C#. It is FALSE. WHY is this false?
Also i dont understand why i needed to create the bool operator in this example but not the one in my other question but no matter. Why is the below false? it makes no sense to me.
BTW the logic making the below false is described here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyInt a=1, b=2;
bool res=a && b;
Console.WriteLine("result is {0}", res);
}
class MyInt
{
public int val;
public static bool operator true(MyInt t) { return t.val != 0; }
public static bool operator false(MyInt t) { return t.val == 0; }
public static MyInt operator &(MyInt l, MyInt r) { return l.val & r.val; }
public static MyInt operator |(MyInt l, MyInt r) { return l.val | r.val; }
public static implicit operator MyInt(int v) { return new MyInt() { val = v }; }
public static implicit operator bool(MyInt t) { return t.val != 0; }
}
}
}
In C there is no bool. Convention is that 0 is false and != 0 is true. if statement treated conditional expression result exactly that way.
In C++ bool was introduced. But it was compatible with old rules, 0 treated as false and false as 0, and there was implicit conversion between int and bool.
In C# it is not the same way: there is bool and int and they are not convertible to eachother. That is what C# Standard says. Period.
So when you tried to reimplement bool and int compatibility you made a mistake. You use && which is logical operator, but in C# you can't override it and only &, which is implemented as bitwise. 1 & 2 == 0 == false! here it is!
You even should not overload bitwise ones, to maintain compatibility you just have to leave operator true and false.
This code works as you expect:
class Programx
{
static void Main(string[] args)
{
MyInt a = 1, b = 2;
bool res = a && b;
Console.WriteLine("result is {0}", res);
}
class MyInt
{
public int val;
public static bool operator true(MyInt t)
{
return t.val != 0;
}
public static bool operator false(MyInt t)
{
return t.val == 0;
}
public static implicit operator MyInt(int v)
{
return new MyInt() { val = v };
}
public static implicit operator bool(MyInt t)
{
return t.val != 0;
}
}
}
result is True
Your implementations of operator& and operator| are wrong. These binary operators have bitwise meanings when applied to integral types, and when applied to either Boolean types or classes that have their own & and | operators, they have logical AND and OR semantics (being the non-short-circuiting cousins of && and ||). Correct implementations would look as follows:
operator &(MyInt l, MyInt r) {return l.val != 0 && r.val != 0);}
operator |(MyInt l, MyInt r) {return l.val != 0 || r.val != 0);}
I'll try and make this simple, since I think people are overcomplicating this.
var x = 1 & 2;
// behind the scenes: 0001 AND 0010 = 0000
Console.Write(x); // 0, as shown above
Integers can NOT be used as booleans in C#. The result of:
if (1 && 2) // compile error
var x = 1 && 2; // compile error
There is no point to asking why an Integer can not be used as a boolean in C#, it just can't. The type system does not allow it. If one were to implement their own Integer class, they could provide implicit conversions from their type to bool, but int does not do this. You also have to make a choice when overloading; do you want bitwise behaviour, or logical behaviour. You can not have both.
Some languages allow 0, "", [] as 'falsey' values. C# does not. Get over it, and use a bool if you're doing boolean logic. If all else fails, Convert.ToBoolean on an int will return true for all non-zero values.
public static MyInt operator &(MyInt l, MyInt r) { return l.val & r.val; }
If I read the linked article correctly, res = a && b will be "expanded" to:
MyInt.false(a) ? a : MyInt.&(a, b)
MyInt.false(a) is false, so evaluates to:
MyInt.&(a, b)
which "expands" to:
a.val & b.val
which is (1 & 2) == 0, and thus false.