Freigeben über


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

  • Anonymous
    March 30, 2006
    Neither 'as' nor 'is' are new keywords in C#.  They've always been there.  The wording of your post seems to suggest otherwise.
  • Anonymous
    March 30, 2006
    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();
    }
  • Anonymous
    March 30, 2006
    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 :-)
  • Anonymous
    March 30, 2006
    The as operator has been around since the first release of C#.
  • Anonymous
    March 30, 2006
    Cast != conversion

    System.Convert.ChangeType is used for conversion.
  • Anonymous
    March 30, 2006
    Thanks for pointing out the typo!
  • Anonymous
    April 05, 2006
  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.
  • Anonymous
    April 05, 2006
    In effort to clear up the confusion, I've updated the original post.
  • Anonymous
    July 17, 2006
    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