Получить сущность из таблицы, используя отражение от абстрактного типа - PullRequest
3 голосов
/ 13 января 2009

Хорошо, у меня есть абстрактный класс с именем Product. У меня есть 3 таблицы, которые называются Предметы, Комплекты и Пакеты, которые реализуют Продукт. Продукт имеет открытое свойство, которое предоставляет первичный ключ объекта.

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

Я хотел сделать что-то подобное, но бросок не примет foo.

public BuilderInclusionsForm(Product p) : this()
        {            
            Type foo = p.GetType();
            product = db2.GetTable(p.GetType()).Cast<foo>().SingleOrDefault(a => 
                a.ProductID == p.ProductID);

или это:

public BuilderInclusionsForm(Product p) : this()
        {            
            Type foo = p.GetType();
            product = db2.GetTable(p.GetType()).OfType<foo>().SingleOrDefault(a => 
                a.ProductID == p.ProductID);   

Ответы [ 2 ]

5 голосов
/ 13 января 2009

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

Вы можете либо сделать универсальный BuilderInclusionForm для типа продукта, либо написать общий метод, подобный следующему:

private static T FindProduct<T>(T product) where T : Product
{
    return db2.GetTable(typeof(T))
                     .OfType<T>()
                     .SingleOrDefault(a => a.ProductID == p.ProductID);
}

, а затем вызвать его с отражением:

public BuilderInclusionsForm(Product p) : this()
{            
    MethodInfo method = typeof(BuilderInclusionsForm).GetMethod("FindProduct",
         BindingFlags.Static | BindingFlags.NonPublic);
    MethodInfo concrete = method.MakeGenericMethod(new Type[] { p.GetType() });
    product = (Product) concrete.Invoke(null, new object[] { p });
}

(Очевидно, вы можете кэшировать открытую форму метода.)

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

public static class BuilderInclusionsForm
{
    public static BuilderInclusionsForm<T> Create<T>(T product) where T : Product
    {
        return new BuilderInclusionsForm<T>(product);
    }
}

, который позволит вам использовать вывод типа.

3 голосов
/ 27 февраля 2009

Благодаря мистеру Скиту яркий член моей команды указал на следующее решение.

public BuilderInclusionsForm(Product p) : this()
{
    IEnumerable<Product> ps = db2.GetTable(p.GetType()).Cast<Product>();
    product = ps.SingleOrDefault(a => a.ProductID == p.ProductID);
}

Извините, что трачу ваше время. Пожалуйста, не собирай мусор, моя жалкая задница, Джон. = Od

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...