C# ‘that’ keyword


My younger brother, Danny, is doing the same graduate program that I did at the University of Florida. Recently he was given a pop quiz from one of my favorite professors where he was asked to describe what the that keyword does in C#. I must admit – I was also initially stumped because I didn’t expect it to be a trick question… I figured maybe, since I focus on J#, I just hadn’t encountered the C# keyword (perhaps it was part of C# 2.0 and I hadn’t noticed). Ok, ok, so really I have no good excuse…

But my question for the readers of my blog: If there was a that keyword for C#, what would it be used for? Accepting all answers, real or absurd. I’ll post the best ones here. BrianKel at Microsoft dot com. Who knows, maybe I’ll ask Dan to champion the best responses with Anders to consider for C# 3.0? :-)


Comments (22)

  1. Simon says:

    I can’t think of a logical reason to add it, it would be superfluous and long winded.

    What would you use it for?

    My only idea would be this:

    foreach (MyType a that IBlarg in myCollection)

    {

    //and get just the MyType’s that support IBlarg as MyType?

    }

    Which, to be honest, is awful and just lazy but it would save on an if statement… It would let you pull out a set of items that support a particular interface or inherit something.

    I certainly wouldn’t WANT it or not want it, but I wouldn’t be averse to using it if it was doing something timesaving.

  2. Sudhakar says:

    "that" keyword in C# ? :S

    I never heard of this…what it can refer to to? which instance? :-)

  3. Three initial thoughts:

    "that" could be used as a keyword in a with statement.

    public int ThatExample<T>(T x, T y) {

    with(System.Collections.Comparer<int>.Default) {

    if(that.Compare(x, y) > 0) {

    return that.GetHashCode(x);

    }

    else {

    return that.GetHashCode(y);

    }

    }

    }

    This usage doesn’t really gain you anything over declaring a variable called "that", except for the implicit typing of "that". However, Anders has already discussed a possible solution to this problem (var).

    My second idea for "that" is an implied variable referring to the return value of a function, similar to VB’s ability to refer to the return value by the method’s name (although it’d be much more concise that repeating the method name over and over).

    Example (same method as above, but using a different definition of "that")

    public int ThatExample<T>(T x, T, y) {

    IComparer<T> comparer = Comparer<T>.Default;

    if(comparer.Compare(x, y) > 0) {

    that = comparer.GetHashCode(x);

    }

    else {

    that = comparer.GetHashCode(y);

    }

    }

    I think this (errr…that) could be more useful. It is often nice in VB to be able refer to the return value directly without declaring a variable. This would be especially useful in factory methods that need to create an object, set lots of properties, call lots of methods, and return the new object. In this case, "that" is also implicitly typed to the return type of the method.

    My third idea involves double virtual dispatch, but I cannot come up with a good example or syntax. Besides, I’m not sure how easily double-dispatch could be implemented in C# and/or the CLR.

  4. It’s part of the debugger support in the CLR. When debugging a problem you can’t track down you may well see references to

    that.methodCall()

    where the that keyword refers to the actual object you should be using, instead of the one you mistakenly codeded.

  5. Anonymous says:

    The that Keyword, yes its in the same namespace as the SoWhatIf condition isnt it ?

  6. vnrg says:

    it sounds to me as equivalent of VB.NET "My" keyword ;)

  7. Never heard of the ‘that’ keyword, but wouldn’t it just be fun if it was the C# term for ‘My’. After all ‘this’ is this and ‘that’ would obviously be that.

    lol

    ;)

  8. Some Guy says:

    The ‘that’ keyword is an implicit reference to a copy of the ‘this’ object that is used when making deep copies (via .Clone() or an equivalent). So if you wanted to deep copy an object like:

    class X : ICloneable {

    private SomeOtherDeepCopyableClass data;

    [UsesCopy]

    public override object Clone() {

    that.data=(SomeOtherDeepCopyableClass)data.Clone();

    }

    }

    Note that ‘that’ is enabled by the "UsesCopy" attribute and is implicitly returned if no other return statement is encountered.

  9. James says:

    int i that playsgolf();

    I don’t know what it could do, but an integer that played golf could prove to be entertaining–at least for a few seconds.

  10. Scott Simons says:

    The that keyword is short hand for what is on the left hand side of the equals sign, a = that + b. It gets mildly confusing when you have a boolean expression a == b + that == c + that. The first that is equal to a and the second that is equal to b + a.

  11. Anonymous says:

    I think it would be perfect for any binary operator overloading. Now you dont have to two arguments. You will endup referencing it implicitly.

    this.ID == that.ID ..

    Also, it can probably be used in AOP (if .NET supports it v5.0 ;)) to provide modification semantics (deleted, inserted) similar to SQL triggers.

  12. Steven Don says:

    Could be useful in operator overloading. Binary operators. People often use a variable "rhs" or something. "that" could be used to make it implicit.

  13. Ryan says:

    Maybe testing object equality? I don’t mean the values in the object A match the values in object B, I mean A and B point to the same object in memory. Maybe syntax like:

    if(A is that B){…}

  14. anony says:

    you’d add a With keyword essentially equivalent to VB’s version, and within the With block, "that" would refer to would refer to the with’d object so that you can pass it to other methods.

    For example:

    with new Foo()

    {

    WhateverProperty = "property";

    IntProperty = 1;

    //call Whatever with the Foo we just made

    //before calling entering the block

    Bar.Whatever(that);

    }

  15. vnrg says:

    it sounds like a VB.NET "My" equivalent,

    and please dont’t refer to Dan ;)

  16. Flier Lu says:

    I think use ‘that’ keyword to support double virtual dispatch pattern is a great idea. Without a special keyword, we need implement that pattern like C++

    interface Shape

    {

    void intersect(Shape shape);

    void intersect(Circle circle);

    void intersect(Rectangle circle);

    }

    class Circle : Shape

    {

    public void intersect(Shape shape)

    {

    Console.Out.WriteLine("Circle::intersect(Shape)");

    shape.intersect(this);

    }

    public void intersect(Circle circle)

    {

    Console.Out.WriteLine("Circle::intersect(Circle)");

    }

    public void intersect(Rectangle circle)

    {

    Console.Out.WriteLine("Circle::intersect(Rect)");

    }

    }

    class Rectangle : Shape

    {

    public void intersect(Shape shape)

    {

    Console.Out.WriteLine("Rect::intersect(Shape)");

    shape.intersect(this);

    }

    public void intersect(Circle circle)

    {

    Console.Out.WriteLine("Rect::intersect(Circle)");

    }

    public void intersect(Rectangle circle)

    {

    Console.Out.WriteLine("Rect::intersect(Rect)");

    }

    }

    class EntryPoint

    {

    [STAThread]

    static void Main(string[] args)

    {

    Shape circle = new Circle();

    Shape rect = new Rectangle();

    circle.intersect(rect);

    }

    }

    This implementation is dirty, because of first, base interface Shape need known all the derived type like Circle or Rectangle, but that type will be add from out of group; second, any type like Circle inherited from Shape, need override Shape::intersect(Shape) to do the second virtual dispatch, and that code has same syntax with difference semantic; third, this code excerpt looks nasty :P

    So we need a keyword to make it simple, like a ‘that’ keyword to access the object, same to ‘this’ object, but with real type bounded, like

    abstract class Shape

    {

    virtual public void intersect(Shape shape)

    {

    shape.intersect(that);

    }

    }

    class Circle : Shape

    {

    override public void intersect(Circle circle)

    {

    Console.Out.WriteLine("Circle::intersect(Circle)");

    }

    override public void intersect(Rectangle circle)

    {

    Console.Out.WriteLine("Circle::intersect(Rect)");

    }

    }

    classs Rectangle : Shape

    {

    //…

    }

    Here the expression "shape.intersect(that);" has a compiler supported semantic, like

    abstract class Shape

    {

    virtual public void intersect(Shape shape)

    {

    //shape.intersect(that);

    Type type = shape.GetType();

    MethodInfo method = null;

    while(type != null && method == null)

    {

    method = type.GetMethod("intersect", new Type[] { this.GetType() });

    type = type.BaseType;

    }

    if(method != null)

    method.Invoke(shape, new object[] { this });

    }

    }

    With ‘that’ keyword, we can only define a simple base class, will not affect other types by defining an arbitrary type.

    btw: some http://www.blogcn.com/User8/flier_lu/index.html?id=3968327

  17. Ed Kaim says:

    I found this in the docs:

    The "that" keyword enables a developer to easily refer to another arbitrary object when focusing their attention on the other, more important objects at hand. The runtime will attempt to pick an object that fits within context (such as when "that" is used as a parameter to a method), but, failing that, will choose a class with a name that shares some of the same letters.

    Be careful not to overuse the "that" keyword in that the optimizing compiler will often share global pointer space between "that" objects and objects referred to via "the_other_thing", resulting in volatile conditions when multiple applications are simultaneously using other classes in System.Abstraction.Obfuscation.Indirection.

    Also be aware of "that"’s default requirement of 66 bits, of which bits 0-31 are used as an address pointer, 32-63 are used as a redundant backup copy of bits 0-31, bit 64 is a flag that indicates if "that" is currently in use while bit 65 tells you whether or not the value in bit 64 must be inverted before usage.

    Hope this helps.

  18. Just to give C# developers more rope to hang themselves with, let’s make "that" an object reference to the caller. And you thought "typeof" was dangerous…

    We could implement the "friend" concept at runtime or, even better, the "private" access modifier:

    public class B

    {

    public void CallFriend()

    {

    class A = new A();

    A.SharedWithB();

    }

    }

    public class A

    {

    public void SharedWithB()

    {

    if (typeof(that) != typeof(B))

    {

    throw new He’sNotAFriendException();

    }

    }

    public void PrivateMethod()

    {

    if (this != that)

    {

    Throw new Wait,That’sNotMe!Exception();

    }

    }

    }

  19. Paul says:

    I can think of one BRILLIANT use for ‘that’… the ?: operator.

    resultstring = (something.GetErrorMessage() == null) ? "worked OK!" : that;

    Where ‘that’, in this case, would refer to something.GetErrorMessage() variable. Not sure how the hell the parser would know which ‘bit’ of the pre-? expression you were referring to, of course, but if it could (in Fantasy World), well, how good would that be?

  20. C#ではThat(VB新機能のMy に対するwrapper)