'is' keyword:

Syntax:
variable is type
-> 'is' keyword is used to identify type of a variable. -> 'is' keyword can be used to identify both reference type and value type. -> The expression always evaluates to a Boolean value. - "true" if the provided type is of the mentioned type - "false" if the provided type is of different type or null. -> 'is' keyword doesn't throw exception when handling null value inside any variable instead it throws false. -> 'is' keyword can be used to identify both reference type and value type.
Example 1:
public partial class Test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        A a = new A();
        bool q1 = a is A; // true - reference type
        int x = 100;
        bool q2 = x is int; // true - value type
    }
}
public class A
{

}
Example 2: When null value or object class are involved...
public partial class Test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        A oA = null;
        bool q1 = oA is A; // false
        object o = null;
        bool q2 = o is object; // false
        oA = new A();
        bool q3 = oA is object; // true
    }
} 
public class A
{

}

'as' keyword:

Syntax:
reference variable as reference type
-> 'as' keyword is used to perform conversion between compatible reference types. -> 'as' keyword is also known as cast operator. -> 'as' keyword is frequently used for upcasting and downcasting in an object in place of implicit or explicit conversion of types. -> 'as' keyword returns "null" if conversion is not possible, instead of throwing exception.
Example 1: as_keyword
(1) For ease of understanding, it is better to use Ultimate base class object reference variable (o) during upcasting and Ultimate derived class object reference variable (c) during downcasting. Usage of immediate base or derived class object reference makes performance lot better when the inheritance hierarchy is too big.
(2) Both the source code does the same operation but the left has side code is preferred as better code because it uses as keyword and thus never gives exception when upcasting is mishandled by the user. At line 6 and 7, as keyword is used which is shown just for understanding. During downcasting there is no way of getting an exception and hence as keyword is never used for downcasting.
(3) It is a standard practise to use as keyword for upcasting in C# instead of using explicit conversion since it is easily for the developers to read and understand the code.

(Advanced Tips: Refer Exception Handling and order of Catch block parameter for deep understanding about performance degradation caused by usage of most parent class in upcasting)

Example 2:
public partial class Test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Exam ex = new Exam();
        GetTestDetails(ex);
    }
    public void GetTestDetails(Object o)
    {
        if (o is UnitTest) // false
        {
            UnitTest ut = o as UnitTest;
            ut.GetTestNo();
        }
        else if (o is Exam) // true
        {
            Exam ex = o as Exam;
            ex.GetSubjectName(); // C #
        }
    }
}
public class Exam
{
    public string GetSubjectName()
    {
        return "C#";
    }
}
public class UnitTest
{
    public int GetTestNo()
    {
        return 1;
    }
}

(1) Notice that the syntax of declaration of method GetTestDetails (i.e.signature) contains Object class object reference variable as input parameter, since object class is the ultimate parent class of any class in C#.
(2) Whatever may be the parameter passed by the callers of this method, downcasting will be done automatically (i.e. implicit conversion). In this case "ex" reference variable belong to type / class "Exam" is passed into the parameters of GetTestDetails(ex) calling statement.
(3) You must be knowing by now that, using one reference variable, it is possible to access the base and derived class objects using upcasting and downcasting operation. Try to attain more clarity by debugging source code in visual studio for complete understanding.
(4) It is important to keep in mind which is the ULTIMATE DERIVED CLASS so that explicit conversion during upcasting will not be mishandled by the user to raise an exception by upcasting to a get reference of class object which never exists in current object in heap memory.
(5) Usage of as keyword will not raise any exception if upcasting is done from most derived class or looking for a class object which doesn't exist in current object, instead as keyword returns null value for the particular casting expression.