SYSK 94: as, is, where keywords in C#


There are a few keywords one should be aware of:


 


The as operator is similar to a cast but on any conversion failure null is returned as oppose to raising an exception.  Note: it will not do the conversion (cast != data type conversion)! 


 


Personally, I prefer not to use this operator, and, instead, use:


      if (x is MyType)


            // do the logic


      else


           // log error


 


As you can see, the is operator, which existed for some time, is used to check whether the run-time type of an object is compatible with a given type.


 


However, there are cases where as operator is useful.  For example, I’ve personally used it in helper classes as described by code snippet below:


    public class CompareHelper<T>


    {


        public int Compare(object data1, object data2)   // similar to string.compare


        {


            int result = 0;  


            if (typeof(T) == typeof(bool))


                result = Compare(data1 as bool, data2 as bool);


            else if (typeof(T) == typeof(string))


                result = Compare(data1 as string, data2 as string);


           else if (typeof(T) == typeof(SomeCustomClass))   // perhaps this calls for some property call


                result = Compare(data1 == null ? 0m : (data1 as SomeCustomClass).SomeDecimalProperty, data2 == null ? 0m : (data2 as SomeCustomClass).SomeDecimalProperty);


            . . .


        }


       


        public int Compare(bool data1, bool data 2)


        {


             . . .


        }


        public int Compare(decimal data1, decimal data 2)


        {


             . . .


        }


        . . .


    }


 


Finally, the new where keyword is used to specify constraints on the types that can be used as arguments for a type parameter defined in a generic declaration.  For example:


 


namespace Test


{


    public class Z


    {


        public virtual void Test()


        {


            System.Diagnostics.Debug.WriteLine(“Z.Test”);


        }


    }


 


    public class Y : X


    {


        public override void Test()


        {


            System.Diagnostics.Debug.WriteLine(“Y.Test”);


        }


    }


 


    public class X


    {      


        public virtual void Test()


        {


            System.Diagnostics.Debug.WriteLine(“X.Test”);       


        }


    }


 


    public class XX<T> where T : X


    {


        public virtual void Test()


        {


            System.Diagnostics.Debug.WriteLine(“XX.Test”);


        }


    }


 


    public partial class Form1 : Form


    {


                . . .


 


        private void button1_Click(object sender, EventArgs e)


        {


            XX<X> o1 = new XX<X>();


            o1.Test();


 


            XX<Y> o2 = new XX<Y>();


            o2.Test();


 


            // this line will fail at compile time with error:


            //    The type ‘Test.Z’ must be convertible to ‘Test.X’ in order to use


            //    it as parameter ‘T’ in the generic type or method ‘Test.XX<T>’


            XX<Z> o3 = new XX<Z>();                


            o3.Test();


        }


    }


}


 


So, go ahead, let the compiler do the work – use these operators to write solid code!


 

Comments (9)

  1. ToddM says:

    Neither ‘as’ nor ‘is’ are new keywords in C#.  They’ve always been there.  The wording of your post seems to suggest otherwise.

  2. Kristoffer says:

    What do you mean by not doing the conversion?

    For efficiency as should be faster than an is and a typecast later as it only involves a single operation.

    MyType x = y as MyType; // Class check here

    if (x != null)

    {

     x.DoSomething();

    }

    Whereas the is operator needs two operations to be useful most of the time:

    if (y is MyType)  // Class check here

    {

     MyType x = (MyType)y; // Class check here

     x.DoSomething();

    }

  3. Ian Horwill says:

    The "as" operator _does_ do the conversion. That’s the point, you can test and convert in one go. If you use "is" instead you have to do the test and then (if the test succeeds) do the conversion.

    This is one of the features I miss as a VB.NET programmer 🙂

  4. Huh says:

    The as operator has been around since the first release of C#.

  5. irenak says:

    Cast != conversion

    System.Convert.ChangeType is used for conversion.

  6. irenak says:

    Thanks for pointing out the typo!

  7. Ron Krauter says:

    1) The statement

    Note: it will not do the conversion!

    is confusing.

    2) You are, IMHO, making the wrong recommendation. In the example you gave, "as" should be used instead of "is" – as some comments above have stated.

    Do you plan on defending your recommendation or correcting it? Thanks.

  8. irenak says:

    In effort to clear up the confusion, I’ve updated the original post.

  9. RGabo says:

    You are doing a lot of boxing and unboxing with CompareHelper<T>, passing in value types as references. If extensively used, this will degrade performance.

    You could do CompareHelper<T> where T : class and let the compiler know you can do data1 as <…> in public int Compare(T data1, T data2).

    This is a problem I’ve seen with generics, where I can’t deal with value and reference types in a generic method at the same time.

    Gabor