-2

I can define an extension method to determine if an object is null

public static bool IsNull(this object obj) {
    if (obj == null)
        return true;
    else return false;
}

But I can also do this:

public static bool IsNull<T>(this T obj) {
    if(obj == null)
        return true;
    else return false;
}

Both are being applied to every object. What's the purpose of this T? To further elaborate what type is being expected? If yes, why this: typeof(T) is possible? And what's the reason behind (this T obj) where T: int) (where) then? (this doesn't work anyway as pointed out by @MatthewWatson)

So many questions.

Atrotygma
  • 1,133
  • 3
  • 17
  • 31
  • You can't have `where T: int`, it's a compile error. Where did you see that? – Matthew Watson Jun 19 '13 at 13:00
  • 3
    Did you [read the manual](http://msdn.microsoft.com/en-us/library/twcad0zb%28v=vs.110%29.aspx) [first](http://msdn.microsoft.com/en-us/library/d5x73970.aspx)? – Jon Jun 19 '13 at 13:01
  • 1
    [Generic Type Parameters](http://msdn.microsoft.com/en-us/library/0zk36dx2.aspx) and [Constraints on Type Parameters](http://msdn.microsoft.com/en-us/library/d5x73970.aspx) – Oded Jun 19 '13 at 13:02
  • Aside: the function can (and **should**) be written as `return obj == null;` instead of that three-line `if` statement that you have. What’s more, that code is actually correct for argument type `object` but incorrect for `T` – in the latter case you instead need to write `object.ReferenceEquals(obj, null)`, you cannot use `==`. – Konrad Rudolph Jun 19 '13 at 13:08
  • @KonradRudolph I thought those were really the same; can you show an example where they are not? – Tim S. Jun 19 '13 at 13:08
  • @TimS. So they are, my mistake. They are *not* the same for non-generic types that overload `operator==`, which is why I was misled (NB: the observable effect *should* be the same for a proper implementation of `operator==` …). – Konrad Rudolph Jun 19 '13 at 13:14
  • @KonradRudolph Right, C# generics don't work like C++ templates: the method doesn't get compiled for every instantiation, it gets compiled once, for all possible instantiations. `==` is resolved to the built-in reference comparison before the concrete type is known. About your NB: do you really mean to suggest that given two strings, say `s1` and `s2`, it is poor design that `s1 == s2` compares the characters that make up the strings? The observable effect is different from `object.ReferenceEquals(s1, s2)`. –  Jun 19 '13 at 13:17
  • @hvd I’m aware of that. I just committed a brain fart. Concerning the NB: `object.ReferenceEquals(s1, s2)` implies `s1 == s2`, not necessarily the other way round. That’s what I meant. – Konrad Rudolph Jun 19 '13 at 13:28
  • @KonradRudolph Ah, okay, so to put it another way, `x == x` for all `x`? If so, pretty much agreed, any `x` for which `x == x` compiles but returns `false` will cause enough problems that you'd better have a *really* good reason for doing that. –  Jun 19 '13 at 13:34

3 Answers3

5

The T is a type argument for a Generic method.

See here for MSDN documentation about generics: http://msdn.microsoft.com/en-us/library/512aeb7t.aspx

It's not specifically to do with extension methods; it's just to do with generics.

Sven
  • 21,903
  • 4
  • 56
  • 63
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
3

T means generic. It means that the type is not known. By default its an object as everything is an object in .Net. But you can specialize T with where paradigm. For instance where T is IDisposable. Then your function will only apply to IDisposable types.

Lionel D
  • 317
  • 1
  • 10
1

T historically means Type. It is used by convention to define generic (in C++ - template) paramteres. In you example it is not necessay because any object in .NET infrastructure inherits base object.

But remember good old days of C++, when C# even wasn't introduced. C++ has only plain type without common parent (i.e. object). So developers was forced to use something to tell to compiler "here something will be substituted, actually I don't know what exactly, but later, at compile-time it will be clear. Do it for me, please".

Returning to notation, in MFC another prefix was used - C like CString.

UPD: You first example will not works because it is extension and null object has not any methods, even you IsNull.

UPD1: Do not read UPD above, the cake is lie.

Alex G.P.
  • 9,609
  • 6
  • 46
  • 81
  • 2
    @AlexGP what do you mean by "will not works"?. It works perfectly fine: `String myObj = null; Console.WriteLine(myObj.IsNull)` ==> "True" – Atrotygma Jun 19 '13 at 13:25
  • 1
    @Alex : that is not right , you can look into http://stackoverflow.com/questions/847209/in-c-what-happens-when-you-call-an-extension-method-on-a-null-object for explanation. – srsyogesh Jun 19 '13 at 13:47
  • @Atrotygma ahh, you area absolutely right, I am afraid of nulls a bit =) – Alex G.P. Jun 19 '13 at 14:32
  • @srsyogesh my fault, I forgot how this sample compiled to IL. – Alex G.P. Jun 19 '13 at 14:38