Embedded statement error [duplicate]

2019-09-22 12:25发布

问题:

This question already has an answer here:

  • Variable declarations following if statements 4 answers

I have a simple custom list class and I am trying to implement IComparable to it, but it's not working to be honest. I tried MSDN and other blogs and still same.

public class sortDateTime : IComparable
{
    protected DateTime m_startDate, m_endDate;

    public DateTime startDate
    {
        get { return m_startDate; }
        set { m_startDate = startDate; }
    }

    public DateTime endDate
    {
        get { return m_endDate; }
        set { m_endDate = endDate; }
    }

    public int CompareTo(object obj)
    {
        if(obj is sortDateTime)
            sortDateTime sDT = (sortDateTime) obj; //here ERROR

         return m_stDate.CompareTo(sDT.m_stDate);
    }
}

Followed this example, but getting the error:

Embedded statement cannot be a declaration or labeled statement

回答1:

Please take a look at the piece of code, resulting in an error:

if(obj is sortDateTime)
    sortDateTime sDT = (sortDateTime) obj; //here ERROR

return m_stDate.CompareTo(sDT.m_stDate);

What you are saying is this:

if the object is of type 'sortDateTime'
    Allocate memory for variable 'sDT'
    Cast 'obj' to type 'sortDateTime' 
    Store the result in variable 'sDT'

And then you are leaving the scope - the variable is not needed anymore (it's allocated on the 'Stack' and get's released). This does not make sense. It's an operation, that get's executed for nothing. What you want to do is the following:

// Variable for remembering the "cast result" after the cast
sortDateTime sDT = null;

if (obj is sortDateTime)
    sDT = (sortDateTime)obj;  // Cast the object.
else
    return 0;                 // "obj" is not an "sortDateTime", so we can't compare.

// Return the comparison result, if we can compare.
return m_stDate.CompareTo(sDT.m_stDate);

The compiler notices that you cannot do such an operation and throws you an error. However this would compile:

if (obj is sortDateTime)
{
    sortDateTime sDT = (sortDateTime)obj;
}

but it would not make sense either, and lead to an compiler error at

m_stDate.CompareTo(sDT.m_stDate);  // sDT is not a variable in scope.

This is how I would implement the method:

sortDateTime sDT = obj as sortDateTime;  // 'as' leads to an casted object, or null if it could not cast

if (sDT == null)
    throw new NotSupportedException("The object is not an sortDateTime");
else
    return m_stDate.CompareTo(sDT.m_stDate);

Cheers!



回答2:

Without checking your logic, I'll fix the syntax error.

This:

public int CompareTo(object obj)
{
    if(obj is sortDateTime)
        sortDateTime sDT = (sortDateTime) obj; //here ERROR

    return m_stDate.CompareTo(sDT.m_stDate);
}

Should be:

public int CompareTo(object obj)
{
    if (obj is sortDateTime)
    {
        sortDateTime sDT = (sortDateTime) obj;
        return m_startDate.CompareTo(sDT.m_startDate);
    }
    else
    {
        throw new ArgumentException("object is not a sortDateTime ");   
    }
}

Look more closely at the page you linked. You didn't follow it properly.



回答3:

Just do like this:

if(obj is sortDateTime) {
     sortDateTime sDT = (sortDateTime) obj; //here ERROR
}

and it will be gone.

For a more concrete explanation on why the compiler behaves in this way, please look on: Why this compile error

Following C# standard naming convention: do not name your types starting with non uppercase letters, so change sortDateTime -> SortDateTime



回答4:

Try this:

public int CompareTo(object obj)
{
    sortDateTime sDT = null;
    if(obj is sortDateTime)
        sDT = (sortDateTime) obj; //here ERROR

    if(sDT != null)
    {
        return m_stDate.CompareTo(sDT.m_stDate);
    }
    else
    {
        throw new ArgumentException("object is not a sortDateTime type.");
    }
}