简体   繁体   中英

Check if generic object of subtype T

I'm trying to refactor the below into a generic function; the code sample below works for me if type is a specified in the function declaration. However, it fails when I try to use T.

I get an IENumerable-like object containing generic objects back from an external application, and from this want to filter out those that are of the specific type in question.

For context, these are geometric features selected on screen by the user prior to the code running. I need to validate that the correct type of thing has been picked, and return those things in a clean list.

Initial code with defined type that works:

    public static List<Point> GetSelectedPoints()
    {
        List<Point> tmp = new List<Point>();

        Selection oSel = GetSelectionObject();

        for (int i = 1; i <= oSel.Count; i++)
        {
            try
            {
                if (oSel.Item(i).Value is Point)
                {
                    Point P = (Point)oSel.Item(i).Value;
                    tmp.Add(P);
                }
            }
            catch
            {
                throw new Exception("An error occurred whilst retrieving the selection");
            }
        }

        return tmp;
    }

Here the attempt to use T:

    static public List<T> GetThisTypeFromSelection<T>()
    {

        Selection osel = GetSelectionObject();
        List<T> tmp= new List<T>();
        for(int i = 1; i<=osel.Count ; i++)
        {
            if (osel.Item(i).Value is T)
            {
                T thing = (T)osel.Item(i).Value;
                tmp.Add(tmp);
            }
        }
        return tmp;
    }

osel.Item(i).Value.GetType() returns a "System.__ComObject"... Which is not helpful.

The object model of the external application is such that everything is derived from a single base class, with many layers of subclassing, something like this:

    public class Base
{}

public class Geometry2d : Base
{ }
public class Line : Geometry2d
{ }
public class Circle : Line
{ }
public class Face : Geometry2d
{ }
public class PlanarFace : Face
{ }
public class CylindricalFace : Face
{ }
public class PlanarFaceDefinedThroughX : PlanarFace
{ }
public class PlanarFaceDefinedThroughY : PlanarFace
{ }
etcetera...

So, The selection object (while also deriving from base) returns a list of base object which could be...pretty much anything.

Depending on the application for this function, I might want to get, for example, everything that's a "Face" or derivative, or maybe just the PlanarFaces, or maybe even just the PlanarFaceDefinedThroughXs.

选择对象如下所示:


Update based on comments (kudos to mm8 pointing in the right direction)

    static public List<T> GetThisTypeFromSelection<T>()
    {

        Selection osel = GetSelectionObject();
        List<Base> listA = new List<Base>();
        for(int i = 1; i<=osel.Count ; i++)
        {
            CATBaseDispatch CbD = osel.Item(i).Value;
            listA.Add(CbD);
        }
        List<T> results = listA.Select(x => x).OfType<T>().ToList();

        return results;
    }

This approach seems to successfully filter out the right object types - but the returned list still shows them as COM objects...

在此处输入图片说明

如果您的Selection实现IEnumerable ,则可以使用Linq的OfType过滤所需类型的项目。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM