Divan
Divan

Reputation: 402

Ternary operator error, on valid if: else; statement

I have a valid if: else; code section as follows:

var obj = new Object();
if(Validation.IsDirectory(fileName))
{
   obj = Activator.CreateInstance(typeof(FilePath));
}
else
{
   obj = Activator.CreateInstance(typeof(FileName));
}

The above generates no error. But, if I translate this to a shorthand if statement, like below:

Validation.IsDirectory(fileName) ? obj = Activator.CreateInstance(typeof(FilePath)) : obj = Activator.CreateInstance(typeof(FileName));

I get the error:

Error CS0201 Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement

In that error documentation it clearly states that:

...Invalid statement is any line or series of lines ending in a semicolon that does not represent an assignment (=), method call (), new, -- or ++ operation.

But out of my first 3 statements the first is a method call and the last two are assignment operations.

So, why am I receiving this error? And how do I write this statement as a shorthand if statement?

Upvotes: 1

Views: 77

Answers (3)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112602

You cannot make the assignment inside the ternary operator. This operator is used in expressions and yields a value that you then can assign. Also, since now we have a single assignment, we can merge this with the declaration.

(Btw., the initialization expression new Object() in your declaration is superfluous, as the following statements replace this object anyway. object obj; would suffice.)

object obj = Validation.IsDirectory(fileName)
    ? Activator.CreateInstance(typeof(FilePath))
    : Activator.CreateInstance(typeof(FileName));

However, you can simplify this further and call the Activator only once by applying the ternary operator the Type arguments only:

object obj = Activator.CreateInstance(
    Validation.IsDirectory(fileName) ? typeof(FilePath) : typeof(FileName)
);

It would be easier to work with FilePath and FileName if they had a common base class that you would use instead of object. The same pattern is used in the System.IO Namespace namespace with the DirectoryInfo Class and the FileInfo Class. Both derive from System.IO.FileSystemInfo and share common members like Name, FullName or Delete().

Upvotes: 3

David
David

Reputation: 218961

The ternary conditional operator is not "a shorthand if statement". The ternary operator is an expression which resolves to a value.

In your attempt it would be structurally similar to a line of code which is nothing more than a value:

4;

This line of code is not a statement, hence the error.

You can use the result of the expression as part of a statement. For example:

var x = 4;

Or in your case:

var x = someTernaryExpression;

Which would be:

var obj = Validation.IsDirectory(fileName) ? Activator.CreateInstance(typeof(FilePath)) : Activator.CreateInstance(typeof(FileName));

In short...

  • When you want to conditionally perform an operation, use if.
  • When you want to conditionally resolve to a value inline, use ?:.

Upvotes: 2

Ma3x
Ma3x

Reputation: 6579

You perform the assignment as a result of (i.e. after) the ternary operator

obj = Validation.IsDirectory(fileName) ? Activator.CreateInstance(typeof(FilePath)) : Activator.CreateInstance(typeof(FileName));

The ternary operator does the check and returns the first value when true, otherwise it returns the second value.

The returned value can then be assigned normally.

Upvotes: 1

Related Questions