I have to agree with daat99 on this one...daat99;628662 said:This will NEVER crash in c# (it may on vb depends on your compilation settings).Code:if ( m != null && m.Mana >= 50)
arul;629159 said:Then you probably used a wrong operator. Replacing '&&' with only '&' is a common mistake.
Yes, I did. Though I don't believe it's the same line that threw the exception you mentioned.Lord_Greywolf;629215 said:did you read the line that threw the exception - it is an && there and not just an & - it would not eeven compile if i used just an & there
it may not check the 2nd half on a null check, but it does when it is not a null check
Lord_Greywolf;629215 said:did you read the line that threw the exception - it is an && there and not just an & - it would not eeven compile if i used just an & there
it may not check the 2nd half on a null check, but it does when it is not a null check
if ( o [B]!= null[/B] && o.class > 4 )
if ( o [B]is B[/B] )
if ( ((B)o).class > 4 )
if ( o [B]is B[/B] [B][COLOR="Red"]&&[/COLOR][/B] ((B)o).class > 4 )
arul;629230 said:As for compiling with '&', it would compile just fine, there's no reason why it shouldn't. And even more, it would have thrown the exception you mentioned! *blink*
daat99;629323 said:Actually single & will do bitwise check between 2 numbers.
While the second part of the if statement will return a number the first part will return a boolean.
I think (99%) it won't compile that particular mistake but I can't check this atm so I'm not 100% sure.
daat99;629323 said:Seperating the if statement into 2 lines will still throw the invalid cast exception.
Again if you disagree than show some code and relevant crash log, you won't get it...
What you're saying is impossible because of a simple fact.
PackHorse can and will not be null so it'll pass the first check regardless if it's on the same line or not, this will crash on the second line.
Up to this point I showed real code that you didn't even bothered to test yourself while you only quoted what you "remember".
Show some real code that support your claim and stop quoting your memory because you're confusing 2 different things.
Once you'll try to reproduce your crash you'll see that you did 2 different things and you'll see your confusion.
What you did was changing:
with:Code:if ( o [B]!= null[/B] && o.class > 4 )
Notice that the first part of the if statement is different, separating the lines themself have no effect whatsoever on the compiling code:Code:if ( o [B]is B[/B] ) if ( ((B)o).class > 4 )
This is the same:
Code:if ( o [B]is B[/B] [B][COLOR="Red"]&&[/COLOR][/B] ((B)o).class > 4 )
Actually single & will do bitwise check between 2 numbers.
While the second part of the if statement will return a number the first part will return a boolean.
I think (99%) it won't compile that particular mistake but I can't check this atm so I'm not 100% sure.
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ClassA var = new ClassA();
var.Name = "Test";
ClassBase o = var;
try
{
//will not throw exception
if ((o is ClassB) && (((ClassB)o).Name == "Test"))
Console.WriteLine("True 1");
else
Console.WriteLine("False 1");
}
catch (Exception er)
{
Console.WriteLine("First");
Console.WriteLine(er.Message);
}
Console.WriteLine();
try
{
//will throw exception, notice only 1 &
if ((o is ClassB) & (((ClassB)o).Name == "Test"))
Console.WriteLine("True 1");
else
Console.WriteLine("False 1");
}
catch (Exception er)
{
Console.WriteLine("Second");
Console.WriteLine(er.Message);
}
Console.WriteLine();
try
{
//will not throw exception
if ((o is ClassB))
{
if (((ClassB)o).Name == "Test")
Console.WriteLine("True 2");
}
else
Console.WriteLine("False 2");
}
catch (Exception er)
{
Console.WriteLine("Third");
Console.WriteLine(er.Message);
}
Console.WriteLine();
try
{
//throws exception (duh)
if ((o is ClassA) && (((ClassB)o).Name == "Test"))
Console.WriteLine("True 3");
else
Console.WriteLine("False 3");
}
catch (Exception er)
{
Console.WriteLine("Fourth");
Console.WriteLine(er.Message);
}
Console.ReadLine();
}
}
//classes that were used to test, both ClassA and ClassB inherit ClassBase (player PlayerMobile and BaseCreature do Mobile)
class ClassA : ClassBase
{
private string m_name;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
}
class ClassB : ClassBase
{
private string m_name;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
}
class ClassBase
{
private int m_id;
public int ID
{
get { return m_id; }
set { m_id = value; }
}
}
}
private string m_name2;
public string Name2
{
get { return m_name2; }
set { m_name2 = value; }
}
But a single & will check both operands, which would cause a cast exception. So thats why you would use &&noobie;629588 said:greywolf, that code you have written doesnt crash unless you use bitwise operator "&" instead of logical operator "&&".
and you can use bitwise operators with boolean values.
Of coursebtw, you cant cast class A to class B where neither one is some related to other. the compiler wont allow that..
arul;629501 said:It compiles just fine with '&', and works the same way as the '&&' does, except the expected short-circuit evaluation, hence the invalid cast exception.
If you were using && than separating the lines would still throw the exact same crash.Lord_Greywolf said:and converting mine into 2 seperate lines did work as long as the 2nd was a sub of the 1st
Thanks for the example code.mordero;629558 said:As you can see when you run this, the First and Third are fine. They are identical in terms of boolean logic. However, if you look at the second one, using only 1 & will throw a cast error because its still checking the second one (because & is bitwise, so it has to check the second one). So using what you are using would be the third one, but it is identical to the first, so it couldnt be your problem.
if ( root is PlayerMobile && ((PlayerMobile)root).ClassLevel <= 4)
System.InvalidCastException: Unable to cast object of type 'Server.Mobiles.PackLlama' to type 'Server.Mobiles.PlayerMobile'.
if ( root is PlayerMobile)
{
if ((PlayerMobile)root).ClassLevel <= 4)
{
code here for what it does
}
}
Again, this code is from your memory and not a currently compiled code like the code we posted above.Lord_Greywolf;629651 said:i all ready did put up that code, the crash report from it and how i seperated the lines so it would not cause the crash - it is all in there all ready
but here it is again:
the line that caused the crash:
Code:if ( root is PlayerMobile && ((PlayerMobile)root).ClassLevel <= 4)
the crash report from it - what i have left - it has been deleted:
Code:System.InvalidCastException: Unable to cast object of type 'Server.Mobiles.PackLlama' to type 'Server.Mobiles.PlayerMobile'.
and how i made it on seperate lines nested so it does not throw it:
Code:if ( root is PlayerMobile) { if ((PlayerMobile)root).ClassLevel <= 4) { code here for what it does } }
if ( root is PlayerMobile)
{
if ((PlayerMobile)root).ClassLevel <= 4)
{
//code
}
}
if ( root is PlayerMobile && ((PlayerMobile)root).ClassLevel <= 4){
//code
}