简体   繁体   English

检查子对象T的通用对象

[英]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. 但是,当我尝试使用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. 我从外部应用程序中获得了一个类似于IENumerable的对象,其中包含通用对象,因此我想过滤掉所讨论的特定类型的对象。

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: 这里尝试使用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. osel.Item(i).Value.GetType()返回“ System .__ ComObject” ...这没有帮助。

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. 根据此函数的应用程序,我可能想要获取例如“ Face”或派生类的所有内容,或者仅是PlanarFaces,甚至只是PlanarFaceDefinedThroughXs。

选择对象如下所示:


Update based on comments (kudos to mm8 pointing in the right direction) 根据注释进行更新(朝着正确的方向指向mm8)

    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... 这种方法似乎可以成功过滤掉正确的对象类型-但是返回的列表仍然将它们显示为COM对象...

在此处输入图片说明

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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