Thread overview
C#'s 'is' equivalent in D
Oct 10, 2019
Just Dave
Oct 10, 2019
Just Dave
Oct 10, 2019
drug
Oct 10, 2019
Adam D. Ruppe
Oct 10, 2019
Just Dave
Oct 10, 2019
Jonathan M Davis
Oct 10, 2019
jmh530
Oct 10, 2019
H. S. Teoh
Oct 10, 2019
jmh530
October 10, 2019
In C# you can do something like:


    if (obj is Person)
    {
        var person = obj as Person;
        // do stuff with person...
    }

where you can check the type of an object prior to casting. Does D have a similar mechanism? It's so widely useful in the C# realm that they even added syntactic sugar to allow:

    if (obj is Person person)
    {
        // do stuff with person...
    }

I would presume since D has reference objects there must exist some mechanism for this...
October 10, 2019
Even though static solutions would be more performance minded, I'd actually prefer to see the runtime equivalent so I don't have to rethink how I think as performance isn't really my major concern right now.

October 10, 2019
On 10/10/19 6:47 PM, Just Dave wrote:
> In C# you can do something like:
> 
> 
>      if (obj is Person)
>      {
>          var person = obj as Person;
>          // do stuff with person...
>      }
> 
> where you can check the type of an object prior to casting. Does D have a similar mechanism? It's so widely useful in the C# realm that they even added syntactic sugar to allow:
> 
>      if (obj is Person person)
>      {
>          // do stuff with person...
>      }
> 
> I would presume since D has reference objects there must exist some mechanism for this...

```D
      if (auto person = cast(Person) obj)
      {
          // do stuff with person...
      }
```
October 10, 2019
On Thursday, 10 October 2019 at 15:47:58 UTC, Just Dave wrote:
>     if (obj is Person person)

Looks the same as D's

if(auto person = cast(Person) obj) {
  // use person in here
} else {
  // it was some other type
}

October 10, 2019
On Thursday, October 10, 2019 9:47:58 AM MDT Just Dave via Digitalmars-d- learn wrote:
> In C# you can do something like:
>
>
>      if (obj is Person)
>      {
>          var person = obj as Person;
>          // do stuff with person...
>      }
>
> where you can check the type of an object prior to casting. Does D have a similar mechanism? It's so widely useful in the C# realm that they even added syntactic sugar to allow:
>
>      if (obj is Person person)
>      {
>          // do stuff with person...
>      }
>
> I would presume since D has reference objects there must exist some mechanism for this...

D's solution is basically the same as C++'s solution. You cast and then check whether the result is null. So,

if(cast(Person)obj !is null)
{
}

or since using a pointer or reference in an if condition checks whether it's null or not

if(cast(Person)obj)
{
}

and you can even declare a variable that way if you want. e.g.

if(auto person = cast(Person)obj)
{
}

When D's is is used to compare two objects, it checks whether they're equal bitwise. So, it's typically used for comparing pointers or references for equality (whereas using == with references would compare the objects themselves for equality).

- Jonathan M Davis



October 10, 2019
On Thursday, 10 October 2019 at 15:53:20 UTC, Adam D. Ruppe wrote:
> On Thursday, 10 October 2019 at 15:47:58 UTC, Just Dave wrote:
>>     if (obj is Person person)
>
> Looks the same as D's
>
> if(auto person = cast(Person) obj) {
>   // use person in here
> } else {
>   // it was some other type
> }

Excellent!
October 10, 2019
On Thursday, 10 October 2019 at 15:47:58 UTC, Just Dave wrote:
> In C# you can do something like:
>
>
>     if (obj is Person)
>     {
>         var person = obj as Person;
>         // do stuff with person...
>     }
>
> where you can check the type of an object prior to casting. Does D have a similar mechanism? It's so widely useful in the C# realm that they even added syntactic sugar to allow:
>
>     if (obj is Person person)
>     {
>         // do stuff with person...
>     }
>
> I would presume since D has reference objects there must exist some mechanism for this...

You mean something like below:

class Person {
    int id;
    this(int x) {
        id = x;
    }
}

void main() {
    auto joe = new Person(1);
    if (is(typeof(joe) == Person)) {
        assert(joe.id == 1);
    }
}
October 10, 2019
On Thu, Oct 10, 2019 at 03:58:02PM +0000, jmh530 via Digitalmars-d-learn wrote:
> On Thursday, 10 October 2019 at 15:47:58 UTC, Just Dave wrote:
> > In C# you can do something like:
> > 
> > 
> >     if (obj is Person)
> >     {
> >         var person = obj as Person;
> >         // do stuff with person...
> >     }
[...]
> You mean something like below:
> 
> class Person {
>     int id;
>     this(int x) {
>         id = x;
>     }
> }
> 
> void main() {
>     auto joe = new Person(1);
>     if (is(typeof(joe) == Person)) {
>         assert(joe.id == 1);
>     }
> }

Unfortunately, typeof is a compile-time construct, so this will not work if you're receiving a Person object via a base class reference. The correct solution is to cast the base class to the derived type, which will yield null if it's not an instance of the derived type.


T

-- 
LINUX = Lousy Interface for Nefarious Unix Xenophobes.
October 10, 2019
On Thursday, 10 October 2019 at 16:33:47 UTC, H. S. Teoh wrote:
> On Thu, Oct 10, 2019 at 03:58:02PM +0000, jmh530 via Digitalmars-d-learn wrote:
>> On Thursday, 10 October 2019 at 15:47:58 UTC, Just Dave wrote:
>> > In C# you can do something like:
>> > 
>> > 
>> >     if (obj is Person)
>> >     {
>> >         var person = obj as Person;
>> >         // do stuff with person...
>> >     }
> [...]
>> You mean something like below:
>> 
>> class Person {
>>     int id;
>>     this(int x) {
>>         id = x;
>>     }
>> }
>> 
>> void main() {
>>     auto joe = new Person(1);
>>     if (is(typeof(joe) == Person)) {
>>         assert(joe.id == 1);
>>     }
>> }
>
> Unfortunately, typeof is a compile-time construct, so this will not work if you're receiving a Person object via a base class reference. The correct solution is to cast the base class to the derived type, which will yield null if it's not an instance of the derived type.
>
>
> T

Ah, you mean something like below:

class Person {
    int id;
    this(int x) {
        id = x;
    }
}

class Employee : Person {
    int job_id;
    this(int x, int y) {
        super(x);
        job_id = y;
    }
}

void main() {
    import std.stdio : writeln;

    Person joe = new Employee(1, 2);

    if (is(typeof(joe) == Employee)) {
        writeln("here"); //not called in this case
    }
}