2

I'm writing a plug-in for AutoCAD 2014 using C# and the .NET Framework. I extended Autodesk's Table class like so:

public class OpeningDataTable : Autodesk.AutoCAD.DatabaseServices.Table

The idea is that I want to pull a table already drawn on an AutoCAD drawing out of the drawing as an instance of OpeningDataTable so I can manipulate the data with methods I've written. I am doing that like so:

OpeningDataTable myTable = checkForExistingTable(true);

public Autodesk.AutoCAD.DatabaseServices.Table checkForExistingTable(bool isWindow)
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; //Current drawing
            Transaction tr = doc.TransactionManager.StartTransaction();
            DocumentLock docLock = doc.LockDocument();
            TypedValue[] tableItem = new TypedValue[] { new TypedValue(0, "ACAD_TABLE") };
            SelectionFilter tableSelecFilter = new SelectionFilter(tableItem);
            Editor ed = doc.Editor; //Editor object to ask user where table goes, subclass of Document

            using (tr)
            {
                PromptSelectionResult selectResult = ed.SelectAll(tableSelecFilter);
                if (selectResult.Status == PromptStatus.OK)
                {
                    SelectionSet tableSelSet = selectResult.Value;
                    for (int i = 0; i < tableSelSet.Count; i++)
                    {
                        Autodesk.AutoCAD.DatabaseServices.Table tableToCheck = (Autodesk.AutoCAD.DatabaseServices.Table)tr.GetObject(tableSelSet[i].ObjectId, OpenMode.ForRead);
                        String tableTitle = tableToCheck.Cells[0, 0].Value.ToString();
                        if(tableTitle.Equals("Window Schedule") && isWindow == true)
                            return (OpeningDataTable)tableToCheck;
                        if (tableTitle.Equals("Door Schedule") && isWindow == false)
                            return (OpeningDataTable)tableToCheck;
                    }
                }
                return null;
            }
        }

However, I get an error saying that I cannot convert a Table object (the parent class) to an OpeningDataTable object (the child class).

Is there a simple workaround for this issue?

J0e3gan
  • 8,740
  • 10
  • 53
  • 80
Nick Gilbert
  • 4,159
  • 8
  • 43
  • 90
  • 1
    No. You can't cast `a` to `B` unless actual type of `a` is `B` or something that inherits `B`. Here, actual type of your variable is `Table` and you're trying to cast it to `OpeningDataTable`, where `Table` does not inherit `OpeningDataTable`. – MarcinJuraszek Nov 01 '14 at 20:37

2 Answers2

2

You will need to create a constructor for OpeningDataTable that takes Table as a parameter.

The reason that you cannot cast a Table to an OpeningDataTable is that a Table is not an OpeningDataTable just like an object is not an int.

J0e3gan
  • 8,740
  • 10
  • 53
  • 80
Jacob Lambert
  • 7,449
  • 8
  • 27
  • 47
2

You cannot downcast a reference to an object like that, unless it is truly a reference to an object of the child class. For example, the following is fine...

string foo = "Yup!";
object fooToo = foo;
string fooey = fooToo as string;

Console.WriteLine(fooey);  // prints Yup!

...because fooToo is simply referencing a String as an Object: so the downcast works.

Consider using the Decorator design pattern and adding a constructor to OpeningDataTable that accepts a Table arg:

public class OpeningDataTable : Autodesk.AutoCAD.DatabaseServices.Table
{
    private Table _table; // the decorated Table

    public OpeningDataTable(Table table)
    {
        _table = table;
    }

    // <your methods for working with the decorated Table>
}
J0e3gan
  • 8,740
  • 10
  • 53
  • 80