Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C# how can i check if T is of type IInterface and cast to that if my object supports that interface?

In C#, I have a function that passes in T using generics and I want to run a check to see if T is an object that implements a interface and if so call one of the methods on that interface.

I don't want to have T constraints to only be of that Type. Is it possible to do this?

For example:

public class MyModel<T> : IModel<T> where T : MyObjectBase
{
    public IQueryable<T> GetRecords()
    {
        var entities = Repository.Query<T>();
        if (typeof(IFilterable).IsAssignableFrom(typeof(T)))
        {
            //Filterme is a method that takes in IEnumerable<IFilterable>
            entities = FilterMe(entities));
        }
        return entities;
    }

    public IEnumerable<TResult> FilterMe<TResult>(IEnumerable<TResult> linked) where TResult : IFilterable
    {
        var dict = GetDict();
        return linked.Where(r => dict.ContainsKey(r.Id));
    }
 }

The error that I am getting is:

Error 21 The type 'TResult' cannot be used as type parameter 'TResult' in the generic type or method 'FilterMe(System.Collections.Generic.IEnumerable)'. There is no implicit reference conversion from 'TResult' to 'IFilterable'.

like image 865
leora Avatar asked Apr 25 '13 03:04

leora


People also ask

What is %A in C?

Modulus AND assignment operator. It takes modulus using two operands and assigns the result to the left operand. C %= A is equivalent to C = C % A. <<= Left shift AND assignment operator.

What is << in C?

The << operator shifts the left-hand value left by the (right-hand value) bits. Your example does nothing! 1 shifted 0 bits to the left is still 1. However, 1 << 1 is 2, 1 << 2 is 4, etc.

What is the use of in C?

In C/C++, the # sign marks preprocessor directives. If you're not familiar with the preprocessor, it works as part of the compilation process, handling includes, macros, and more.


2 Answers

The missing piece is Cast<>():

if(typeof(IFilterable).IsAssignableFrom(typeof(T))) {
    entities = FilterMe(entities.Cast<IFilterable>()).AsQueryable().Cast<T>();
}

Note the use of Cast<>() to convert the entities list to the correct subtype. This cast would fail unless T implements IFilterable, but since we already checked that, we know that it will.

like image 161
siride Avatar answered Oct 25 '22 14:10

siride


if (typeof(IMyInterface).IsAssignableFrom(typeof(T))

This checks whether a variable of type IMyInterface can be assigned from an instance of type T.

like image 41
SLaks Avatar answered Oct 25 '22 12:10

SLaks