У меня есть абстрактный общий класс BLL<T> where T : BusinessObject. Мне нужно открыть сборку, содержащую набор конкретных классов BLL, и вернуть кортежи (businessObjectType, ConcreteBLLType) внутри Словаря. Есть часть метода, который я мог использовать до сих пор, но у меня проблемы с обнаружением T.
protected override Dictionary<Type, Type> DefineBLLs()
{
string bllsAssembly = ConfigurationManager.AppSettings["BLLsAssembly"];
Type[] types = LoadAssembly(bllsAssembly);
Dictionary<Type, Type> bllsTypes = new Dictionary<Type, Type>();
foreach (Type type in types)
{
if (type.IsSubclassOf(typeof(BLL<>)))
/* how to know T in the situation below? */
bllsTypes.Add(??businessObjectType (T)??, type);
}
return bllsTypes;
}
Я думаю, что Джон, вероятно, очистил код для вас.





Значит, конкретные классы будут закрытыми, а не универсальными? Вот короткая программа, которая демонстрирует, что вам нужно, считать ...
using System;
using System.Reflection;
public abstract class Base<T>
{
}
public class Concrete : Base<string>
{
}
class Test
{
static void Main()
{
Type type = typeof(Concrete);
Type baseType = type.BaseType;
Type typeOfT = baseType.GetGenericArguments()[0]; // Only one arg
Console.WriteLine(typeOfT.Name); // Prints String
}
}
Обратите внимание, что здесь я предполагая, что нам нужно подняться только на один уровень, чтобы перейти к соответствующему базовому типу, и что конкретный класс воля должен быть закрыт. Вы, конечно, захотите провести больше проверок в своем реальном коде, но я подозреваю, что вам не хватало вызова GetGenericArguments.
Джон, это именно то, что я искал. Я использую основы отражения и обобщения, поэтому, когда требуется более глубокое знание API, чтобы противостоять обоим, я скучаю по таким вещам, как этот, спасибо за ответ.
Ваши предположения верны, конкретные классы закрыты, а T определен в базовом классе (BLL).
Код стал таким:
protected override Dictionary<Type, Type> DefineBLLs()
{
string bllsAssembly = ConfigurationManager.AppSettings["BLLsAssembly"];
Type[] types = LoadAssembly(bllsAssembly);
Dictionary<Type, Type> bllsTypes = new Dictionary<Type, Type>();
foreach (Type bllType in types)
{
if (bllType.IsSubclassOf(typeof(BLL<>)))
{
Type baseType = bllType.BaseType;
Type businessObjectType = baseType.GetGenericArguments()[0];
bllsTypes.Add(businessObjectType, bllType);
}
}
return bllsTypes;
}
Я бы по крайней мере добавил комментарий: «Это сломается, если у нас будет более глубокая иерархия классов!» Просто чтобы вы знали, что не так, когда он взрывается :)
Хорошо, Джон, в моем случае BLL одновременно является непосредственным базовым классом из конкретных, а сам BLL не использует наследование;)
Что ж, к чему здесь Т? Непонятно (по крайней мере, мне), что представляет собой код.