I need to check if a certain property exists within a class. Please refer to the LINQ query in question. For the life of me I cannot make the compiler happy.
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();
开发者_如何学JAVA }
set
{
}
}
}
public class HomeView : View
{
}
public class View
{
}
GetProperties() returns an array of PropertyInfo objects. Your call to p.GetType() is always going to return typeof(PropertyInfo) - never the "view" type you've passed in.
You probably want this instead:
from p in m.Value.GetType().GetProperties()
where p.PropertyType.Equals(view)
select p
Edit
As Robert pointed out, your logic to determine if the above query returns any properties is also wrong. An easy way around that is to see if anything came back from the subquery:
var module = from m in Modules
where (
from p in m.Value.GetType().GetProperties()
where p.PropertyType.Equals(view)
select p
).Any()
select m
Keep in mind that that query might return more than one module. You will probably want to return .First() from the results.
The inner query should return bool
, but returns PropertyInfo
.
I haven't tested this, but I think you want something like:
var module = (from m in Modules
where m.Value.GetType().GetProperties()
.Select(p => p.PropertyType).Contains(view)
select m).FirstOrDefault();
Edit:
Incorporating the Enumerable.Any
suggestion on another answer:
var module = (from m in Modules
where m.Value.GetType().GetProperties()
.Any(p => p.PropertyType.Equals(view))
select m).FirstOrDefault();
The where
keyword expects a predicate that returns a boolean condition, but you are providing a subquery that returns an IEnumerable
. Can you rework your subquery so that it returns an actual boolean condition?
You can convert it to a boolean result by using the FirstOrDefault()
extension method. This method will return null
if there are no records. So this should work (untested):
where ( from p in m.Value.GetType().GetProperties()
where p.PropertyType.Equals(view)
select p ).FirstOrDefault() != null
Even if you can get your query working, I don't think this is a good way to link your model with your view. I'd recommend creating a new question with more detail about what you are trying to do (and why), asking how you can create the association/link between the model and the view.
精彩评论