Какой быстрый способ проверить, является ли ссылка конкретным родовым типом? - PullRequest
0 голосов
/ 07 ноября 2008

Если у меня есть метод с параметром, который является интерфейсом, какой самый быстрый способ узнать, относится ли ссылка к интерфейсу к определенному универсальному типу?

Более конкретно, если у меня есть:

interface IVehicle{}

class Car<T> : IVehicle {}

CheckType(IVehicle param)
{
    // How do I check that param is Car<int>?
}

Я также собираюсь разыграть после проверки. Так что, если есть способ убить двух зайцев одним выстрелом, дайте мне знать.

Ответы [ 6 ]

10 голосов
/ 07 ноября 2008

Чтобы проверить, является ли param Car<int>, вы можете использовать "is" и "as" как обычно:

CheckType(IVehicle param)
{
    Car<int> car = param as Car<int>;
    if (car != null)
    {
         ...
    }
}
3 голосов
/ 07 ноября 2008

Или вы можете просто сделать:

if(param is Car<int>)
{
    // Hey, I'm a Car<int>!
}
1 голос
/ 07 ноября 2008

Код довольно сильно отличается в зависимости от того, хотите ли вы знать, основана ли ссылка на прототипе универсального типа или специализированном.

Специализированный прост, вы можете просто использовать is:

CheckType(IVehicle param)
{
   var isofYourType = param is Car<int>;
   ...
}

или безопасное приведение, как показано ранее:

CheckType(IVehicle param)
{
   var value = param as Car<int>;
   if(value != null)    
       ...
}

Если вы захотите узнать, является ли yur var просто какой-то специализацией Car<T>, все становится действительно ужасным И последнее, о чем вам следует беспокоиться, это скорость в этом случае, потому что это будет даже хуже, чем код g :

class Car<T>
{ }

interface IVehicle { }

class YourCar : Car<int>, IVehicle
{ }

static bool IsOfType(IVehicle param)
{
    Type typeRef = param.GetType();
    while (typeRef != null)
    {
        if (typeRef.IsGenericType &&
            typeRef.GetGenericTypeDefinition() == typeof(Car<>))
        {
            return true;
        }
        typeRef = typeRef.BaseType;
    }
    return false;
}

static void Main(string[] args)
{
    IVehicle test = new YourCar();
    bool x = IsOfType(test);
}
1 голос
/ 07 ноября 2008

Почему бы не сделать это универсальным?

interface IVehicle{}

class Car<T> : IVehicle {

    public static bool CheckType(IVehicle param)
    {
        return param is Car<T>;
    }
}

...

Car<string> c1 = new Car<string>();
Car<int> c2 = new Car<int>();
Console.WriteLine(Car<int>.CheckType(c1));
Console.WriteLine(Car<int>.CheckType(c2));
0 голосов
/ 07 ноября 2008

Используйте оператор «как», чтобы сделать все это за один выстрел. «as» вернет либо объект нужного вам типа, либо null, если то, с чем вы проверяете, не совпадает. Это будет работать только для ссылочных типов.

interface IVehicle { }
class Car<T> : IVehicle 
{
    static Car<int> CheckType(IVehicle v)
    {
        return v as Car<int>;
    }
}

Оператор "is" позволит вам проверить, является ли v экземпляром Car<int>.

0 голосов
/ 07 ноября 2008

Я часто нахожу, что если мой код требует, чтобы я писал проверки для определенных типов, я, вероятно, делаю что-то не так. Вы не дали нам достаточно контекста, чтобы мы могли дать совет по этому вопросу.

Соответствует ли это вашим потребностям?

Car<int> carOfInt = param as Car<int>;
if (carOfInt != null)
{
    // .. yes, it's a Car<int>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...