2015-01-08 4 views
0

У меня есть некоторые (не) общие функции явно присвоенных DbSet (с использованием Entity Framework 6.1, но вопрос более общий характер, в некотором смысле):Достичь общий вызов метода в зависимости от типа данного

//Non-generic type method 
public static IQueryable BuildQuery(this DbSet dbSet) 
{ 
    return dbSet; 
} 
//Generic base class elements method 
public static IQueryable<Entity> BuildQuery(this DbSet<Entity> dbSet) 
{ 
    return dbSet.Include(de1 => de1.NavigationPropertyBase); 
} 
//Derived class 1 elements method 
public static IQueryable<DerivedEntity1> BuildQuery(this DbSet<DerivedEntity1> dbSet) 
{ 
    return dbSet.Include(de1 => de1.NavigationPropertyX); 
} 
//Derived class 2 elements method 
public static IQueryable<DerivedEntity2> BuildQuery(this DbSet<DerivedEntity2> dbSet) 
{ 
    return dbSet.Include(de2 => de2.NavigationPropertyX). 
       Include(de2 => de2.NavigationPropertyY); 
} 

Я знаю, что хотя DerivedEntity1 и DerivedEntity2 продлены Entity, Dbset<DerivedEntityX> не распространяется DbSet<Entity>.

Что я хочу сделать, это достижение позднего связывания как поведение, основанное на родовом типе. Я думал поставить родовой тип в необщий переменный, а затем вызовите метод BuildQuery (видно, как она существует для необщего типа во время компиляции):

//This compiles with no errors. 
DbSet dbSetNonGeneric = dbSet; // dbSet is of DbSet<DerivedEntity1> type 
var result = dbSetNonGeneric.BuildQuery(); 

Моего вопрос, будет ли это приведет к вызову метода BuildQuery в соответствии с общим типом или вызовет его не общий метод? А во втором случае есть ли способ добиться такого рода вызова метода?

ответ

1

Это приведет к вызову метода BuildQuery в соответствии с общим типом или вызовет его не общий метод?

Он будет использовать неоригинальную перегрузку.

А во втором случае есть ли способ добиться такого вызова метода?

Вы можете ввести переменную как dynamic, но тогда результатом будет также dynamic.

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

ОБНОВЛЕНИЕ: поскольку динамический поиск не может найти методы расширения (link), они должны использоваться как обычные статические методы для работы в сочетании с dynamic.

+0

Можете ли вы привести пример использования 'dynamic' и/или использование отражения?Спасибо. –

+0

@NickL. Попробуйте и посмотрите, что произойдет. Если у вас возникли проблемы с изменением типа переменной на «dynamic», то описывайте конкретную проблему, с которой вы сталкиваетесь. – Servy

+0

Ключевое слово 'dynamic' было не очень полезно, так как комбинация с методами расширения на C# проблематична. Ваш ответ мне помог, спасибо вам большое. –

0

Он будет называться неосновным методом. Причина этого проста, что методы расширения вызываются на основе типа переменной, а не типа времени выполнения (производный тип)

Согласно предложению @Servy, вы можете использовать отражение, но у меня есть сомнения относительно dynamic.

Ключевое слово dynamic не будет работать, если у вас есть методы расширения.

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

Следующая ссылка поможет вам получить этот метод и вызвать с помощью отражения.

Reflection to Identify Extension Methods

+0

Вы правы насчет 'dynamic', я закончил тем, что использовал отражение, и эта ссылка была сокровищем. Спасибо! –

+0

@NickL. Dynamic работает с этими методами просто отлично, вы просто не можете использовать синтаксис метода расширения; использование отражения - тонна ненужной занятости. – Servy

+0

Я не уверен, почему downvote, но динамический не работает с методом расширения, и в вопросе используется метод расширения. – dotnetstep