Home > Software design >  Ternary operator error, on valid if: else; statement
Ternary operator error, on valid if: else; statement

Time:07-31

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?

CodePudding user response:

You cannot make the assignment inside the ternary operator. This operator is used in an expression 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 by applying the ternary operator to the common sub-expression 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().

CodePudding user response:

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 ?:.

CodePudding user response:

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.

  • Related