-1

In C# I sometimes have to do something if the object is of some type.

e.g.,

if (x is A)
{
    // do stuff but have to cast using (x as A)
}

What would be really nice if inside the if block, we could just use x as if it were an A, since it can't be anything else!

e.g.,

if (x is A)
{
    (x as A).foo(); // redundant and verbose
    x.foo();   // A contains a method called foo
}

Is the compiler just not smart enough to know this or is there any possible tricks to get similar behavior

Can the Dlang effectively do something similar?

BTW, I'm not looking for dynamic. Just trying to write less verbose code. Obviously I can do var y = x as A; and use y instead of X.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
AbstractDissonance
  • 1
  • 2
  • 16
  • 31
  • Possible duplicate of [Is there an "opposite" to the null coalescing operator? (…in any language?)](http://stackoverflow.com/questions/2929836/is-there-an-opposite-to-the-null-coalescing-operator-in-any-language) – Joe Enzminger Feb 13 '16 at 03:42
  • In c#, typically you'd assign `x` to another variable types as `A` using `x as A`. If `A` was a reference type, then you'd just test if that variable is null, then use it. Your use of `as` there isn't quite what it's meant for. – Jeff Mercado Feb 13 '16 at 03:46
  • It's about scope... `x` on the line of the `if`-statement belongs to the outer scope and is of type `Z`... Inside the `if`-statement `x` is still the same type: `Z`... `(x as A).foo()` casts it to `A` and calls the method `foo()`... The compiler cannot determine that you want type `A` unless you specify it... You can specify `A` or `B` or `C` if you want to... One or all of the above in the same scope... – Sani Huttunen Feb 13 '16 at 03:49
  • 1
    Have a read of Eric Lippert's article [Inferring from “is”, part one](http://ericlippert.com/2015/10/19/inferring-from-is/). – Enigmativity Feb 13 '16 at 03:51
  • You could do `(x as A)?.foo();`. – Enigmativity Feb 13 '16 at 03:53
  • 4
    It is unclear whether your question is only about D or C# and D both. – sigod Feb 13 '16 at 04:32
  • @Enigmativity Thanks, pretty good discussion of it. – AbstractDissonance Feb 13 '16 at 06:41

3 Answers3

6

In D, the pattern you'd usually do is:

if(auto a = cast(A) your_obj) {
    // use a in here, it is now of type A
    // and will correctly check the class type
}
Adam D. Ruppe
  • 25,382
  • 4
  • 41
  • 60
1

For one statement (or chain-able calls) you can use (x as A)?.Foo() in C# 6.0+ as shown in Is there an "opposite" to the null coalescing operator? (…in any language?).

There is no multiple statements version in the C# language, so if you want you'll need to write your own. I.e. using Action for body of the if statement:

  void IfIsType<T>(object x, Action<T> action)
  {
     if (x is T)
          action((T)x);
  }

object s = "aaa";
IfIsType<string>(s, x => Console.WriteLine(x.IndexOf("a")));
Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 1
    Downvoted because the question was "Can the Dlang effectively do something similar?" and the answer is about C#, which the asker just used as an example of what is wanted. The requested answer will be about the D language. – Adam D. Ruppe Feb 13 '16 at 04:16
  • 3
    @AdamD.Ruppe to me question is looking for both C# and D solutions (especially based on last remark "Just trying to write less verbose code. Obviously I can do var y = x as A; and use y instead of X"). If you think there is clear "D-only" - make sure to edit the question to clarify (preferably after confirming with OP), also remove C# tag so future readers are not confused by it. – Alexei Levenkov Feb 13 '16 at 04:22
  • 2
    The question is: `Can the Dlang effectively do something similar?` How can you construe that to mean anything else? The question is essentially, "C# can do this, can D do it too?" – Jeff Mercado Feb 13 '16 at 04:39
  • @JeffMercado I get that I neither can read nor explain my point of view. You could have simply expressed that with "what a moron" comment (also others could consider as "too chatty"). With way you've composed your comment it is unclear what new clarification you expect in response as it seem to be just re-iteration of comment by Adam D Ruppe. – Alexei Levenkov Feb 13 '16 at 05:14
  • lol, shesh, I wanted to know about both cases. I use C# more but I'm writing something that I might want to port to D in the future. – AbstractDissonance Feb 13 '16 at 06:37
  • 2
    In that case, I'll downvote your *question* for being poorly worded. I might be taking out a bad week on y'all, but I'm kinda sick of googling things and getting results on Stack Overflow that seem so promising - someone else has the same problem I have - but are so useless because the answers didn't actually apply. (Or worse yet, the exact problem I have is closed as a duplicate of some problem I don't have! Ugh!) – Adam D. Ruppe Feb 13 '16 at 17:00
0

I believe this is a feature is under consideration for C# 7. See the Roslyn issue for documentation, specifically 5.1 Type Pattern:

The type pattern is useful for performing runtime type tests of reference types, and replaces the idiom

var v = expr as Type;
if (v != null) { // code using v }

With the slightly more concise

if (expr is Type v) { // code using v }`

As for Dlang, I would reference their if statement syntax documentation here.

AGB
  • 2,230
  • 1
  • 14
  • 21
  • 1
    Downvoted because the question was "Can the Dlang effectively do something similar?" and the answer is about C#, which the asker just used as an example of what is wanted. The requested answer will be about the D language. – Adam D. Ruppe Feb 13 '16 at 04:16
  • It reads to me like a two part question. The first part: "Is the compiler just not smart enough to know this or is there any possible tricks to get similar behavior?" Presumably, this question refers to the C# compiler as it immediately follows the C# example. The second part of the question is the one you referenced above. – AGB Feb 13 '16 at 04:32