C # - Помощь с LINQ - PullRequest
       31

C # - Помощь с LINQ

1 голос
/ 21 мая 2010

Мне нужно проверить, существует ли определенное свойство в классе. Пожалуйста, обратитесь к вопросу LINQ в вопросе. Из-за своей жизни я не могу осчастливить компилятор.

class Program
{
    static void Main(string[] args)
    {
        ModuleManager m = new ModuleManager();
        IModule module = m.FindModuleForView(typeof(HomeView));
        Console.WriteLine(module.GetType().ToString());
        Console.ReadLine();
    }
}

public class ModuleManager
{
    [ImportMany]
    public IEnumerable<Lazy<IModule>> Modules { get; set; }

    [ImportMany]
    public IEnumerable<Lazy<View>> Views { get; set; }

    public ModuleManager()
    {
        //An aggregate catalog that combines multiple catalogs
        var catalog = new AggregateCatalog();
        //Adds all the parts found in the same assembly as the Program class
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
        //Create the CompositionContainer with the parts in the catalog
        _container = new CompositionContainer(catalog);
        //Fill the imports of this object
        try
        {
            this._container.ComposeParts(this);
        }
        catch (CompositionException compositionException)
        {
            Console.WriteLine(compositionException.ToString());
        }
    }

    public IModule FindModuleForView(Type view)
    {
        //THIS IS THE PROBLEM
        var module = from m in Modules
                     where (
                        from p in m.Value.GetType().GetProperties()
                        where p.GetType().Equals(view)
                        select p
                     )
                     select m;

    }
    public CompositionContainer _container { get; set; }
}

public interface IModule
{
}

[Export]
public class HomeModule : IModule
{
    public HomeModule()
    {
    }

    [Export]
    public HomeView MyHomeView
    {
        get
        {
            return new HomeView();
        }
        set
        {
        }
    }
}


public class HomeView : View
{
}

public class View
{
}

Ответы [ 4 ]

2 голосов
/ 21 мая 2010

GetProperties () возвращает массив PropertyInfo объектов. Ваш вызов p.GetType () всегда будет возвращать typeof (PropertyInfo) - никогда не передаваемый тип «view».

Вы, вероятно, хотите вместо этого:

from p in m.Value.GetType().GetProperties() 
where p.PropertyType.Equals(view) 
select p 

Редактировать

Как указал Роберт, ваша логика определения того, возвращает ли вышеуказанный запрос какие-либо свойства, также неверна. Простой способ обойти это - посмотреть, что-нибудь получилось из подзапроса:

var module = from m in Modules 
             where ( 
                 from p in m.Value.GetType().GetProperties() 
                 where p.PropertyType.Equals(view) 
                 select p 
             ).Any()
             select m

Имейте в виду, что этот запрос может возвращать более одного модуля. Возможно, вы захотите вернуть .First () из результатов.

1 голос
/ 21 мая 2010

Внутренний запрос должен возвращать bool, но возвращает PropertyInfo.

Я не проверял это, но я думаю, что вы хотите что-то вроде:

    var module = (from m in Modules
                 where m.Value.GetType().GetProperties()
                    .Select(p => p.PropertyType).Contains(view)
                 select m).FirstOrDefault();

Edit:

Включение предложения Enumerable.Any в другой ответ:

    var module = (from m in Modules
                 where m.Value.GetType().GetProperties()
                    .Any(p => p.PropertyType.Equals(view))
                 select m).FirstOrDefault();
1 голос
/ 21 мая 2010

Ключевое слово where ожидает предикат, который возвращает логическое условие, но вы предоставляете подзапрос, который возвращает IEnumerable. Можете ли вы переработать свой подзапрос, чтобы он возвращал действительное логическое условие?

Вы можете преобразовать его в логический результат, используя метод расширения FirstOrDefault(). Этот метод вернет null, если нет записей. Так что это должно работать (не проверено):

where ( from p in m.Value.GetType().GetProperties() 
        where p.PropertyType.Equals(view) 
        select p ).FirstOrDefault() != null
0 голосов
/ 21 мая 2010

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

...