To find the target of an ExpressionSyntax instance I call mySemanticModel.GetSymbolInfo(myExpressionSyntax).
I have several SemanticModel instances that each relate to a code file's syntax tree.
I want to iterate the semantic models and find the appropriate one to return the symbol information, but I can't see how to test for the appropriate semantic model without using exceptions.
I need the following code completing:
SymbolInfo? Resolve(ExpressionSyntax expressionSyntax)
{
foreach (SemanticModel semanticModel in allSemanticModels)
{
if ( /* test if expression syntax found in semantic model */ )
{
return semanticModel.GetSymbolInfo(expressionSyntax);
}
}
return null;
}
SemanticModels are bound to an underlying SyntaxTree, so you just need to make sure those lined up. If you had an IEnumerable<SemanticModel> you'd just have to do:
var model = models.First(m => m.SyntaxTree == expressionSyntax.SyntaxTree);
To pick out the right one; you're probably better off having a Dictionary<SyntaxTree, SemanticModel> rather than enumerating a list each time. I'm not sure exactly why you'd use any other data structure to hold them.
The only main advantage too of holding onto an SemanticModel is you get some caching benefits, trading memory in the process; don't be holding onto SemanticModels you're not going to use anymore.
Related
I have a WPF treeview that is loaded from a set of classes hierarchy (strongly-typed-dataset (Entity Framework).)
I am looking for the correct way to cast these nodes back as one of these objects.
At the moment I have to write code for each class within my hierarchy (This is an example of how I am deleting an object):
if (MainTree.SelectedItem is tblProject)
{
var s = (tblProject)MainTree.SelectedItem;
_context.tblProjects.Remove(s);
}
if (MainTree.SelectedItem is tblLine)
{
var s = (tblLine)MainTree.SelectedItem;
_context.tblLines.Remove(s);
}
if (MainTree.SelectedItem is tblDevice)
{
var s = (tblDevice)MainTree.SelectedItem;
_context.tblDevices.Remove(s);
}
I would like to know how I could reduce this code, and make it more flexible, so that I do not have to add code for each class that I might add in the future.
In case of EF you can use _context.Set(MainTree.SelectedItem.GetType()).Remove(MainTree.SelectedItem)
In general I would recomend to take a look into Data Binding and MVVM patttern to avoid the similar situations
I am trying to write a wrapper function for an application.
This application will continually add entities so it would be better if we could write one generic function rather than have to carve out an exception for each item.
For certain reasons we maintain both a GUID and an int key.
When an int key gets updated, we need to update it both in the parent record the child records but since it is possible that at any given time there could be multiple child records with the same int key, we need to get a list of Guids of what we want to update.
Here is some psuedo code of what I am trying to do.
List<string> depenedents = new List<string>();
depenedents.add(table1);
depenedents.add(table2);
depenedents.add(table3);
for(item in depenedents)
{
context.set<type item>();
entities.getguid();
}
Obviously the issue here is with the for loop.
Is it possible to get a list of entities knowing only the string of the entity type? Luckily all of our entities are wrapped to a base class that has a get guid method, but I need to find a way to actually get the entities.
Any help is greatly appreciated.
Something like:
for(item in depenedents)
{
context.GetMethod("Set")
.MakeGenericType(Type.GetType(item))
.Invoke(context, new object[0]);
entities.GetType.GetMethod("GetGuid").Invoke(entities, new object[0]);
}
...should be with roughly what you need. This will invoke the correct type specialisation of the Set generic instance method. Then it will invoke the instance method called "GetGuid" on the entities object.
Or possibly:
foreach(var entity in entities)
{
entity.GetType.GetMethod("GetGuid").Invoke(entities, new object[0]);
}
You'll maybe want to do something with the values returned, but hopefully this answer will point you in the right direction!
(and clearly you could optimise this code substantially to cache reflected types and methods, or to use compiled expressions rather than Invoke() calls)
I am working on a framework that uses some Attribute markup. This will be used in an MVC project and will occur roughly every time I view a specific record in a view (eg /Details/5)
I was wondering if there is a better/more efficient way to do this or a good best practices example.
At any rate, I have an a couple of attributes e.g:
[Foo("someValueHere")]
String Name {get;set;}
[Bar("SomeOtherValue"]
String Address {get;set;}
What is the most efficient way/best practice to look for these attributes/Act on their values?
I am currently doing something like this:
[System.AttributeUsage(AttributeTargets.Property)]
class FooAttribute : Attribute
{
public string Target { get; set; }
public FooAttribute(string target)
{
Target = target;
}
}
And in my method where I act on these attributes(simplified example!):
public static void DoSomething(object source)
{
//is it faster if I make this a generic function and get the tpe from T?
Type sourceType = source.GetType();
//get all of the properties marked up with a foo attribute
var fooProperties = sourceType
.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(FooAttribute), true)
.Any())
.ToList();
//go through each fooproperty and try to get the value set
foreach (var prop in fooProperties)
{
object value = prop.GetValue(source, null);
// do something with the value
prop.SetValue(source, my-modified-value, null);
}
}
Attribute.GetCustomAttribute and PropertyInfo/MemberInfo.GetCustomAttribute is the recommended way of getting at attribute objects.
Although, I wouldn't normally enumerate all properties with attributes; you generally want to work a particular attribute so you'd just call GetCustomAttribute directly.If you're looking for attributes on any of your properties, enumerating those properties looking for attributes based on GetCustomAttribute() the way you're doing it, is the best way to do it.
There is not really much choice when dealing with attributes - your code is ok and reasonable as is, it is also unlikley to be your main performance concern. The only immediate thing is to drop ToList call as absolutely unnecessary.
Side notes: performance related question should look approximately
"I've measured my code and portion XXX seems to be taking too much time (YYY) . The time goal for this piece of code is ZZZ. Is my way of doing XXX reasonable/where can I improve it?".
Note that in you case you are missing YYY and ZZZ time portions - so you can't really say if it is slow for your case or not. And you may want to start measurements with DB/other IO bound operations as it more likely to speed up your overall code.
After you figured that this attribute related code is main perfomance issue you can consider some sort of caching of results or even code generation of some sort (either through caching lambdas that would set necessary values or even full blown IL generation).
I have a page named "ReportController.aspx" whose purpose is to instantiate a report (class) based on query string parameters
switch (Request.QueryString["Report"])
{
case "ReportA":
CreateReportAReport("ReportA's Title");
break;
case "ReportB":
CreateReportBReport("ReportB's Title");
break;
case "ReportC":
CreateReportCReport("ReportC's Title");
break;
case "ReportD":
CreateReportDReport("ReportD's Title");
break;
...
Basically, each time a new report is needed there will be this overhead of adding a case and adding a method. This switch statement could get very very long. I read that is is possible to use a Dictionary to map a Report to ?. How would this look using a Dictionary (assuming this is a better way).
Also, CreateReportXReport method basically passes a bunch of additional QueryString values to the report class's constructor (each report class has a different constructor).
There's no getting around having to type in the new information somewhere; the key is to get it out of the code, to avoid recompiling and redeploying for such a trivial change.
Some good options are to list these value in an XML config file, or better yet, your database.
You'll probably want to fill out a dictionary with this data, whatever the source. This will:
Make it easy to cache
Make for clean, fast code
When the time comes to pull your data out of configuration into code, you'd add items to the dictionary like so:
Dictionary<string, IReportCreator> = configDataGetter.GetReportDataFromDB().
ToDictionary(r => r.Name, myReportCreatorFactory(r => r.ReportID))
This example assumes your getting data as entity object of some kind, and using a factory that would use a strategy pattern for your code that creates reports. There's a bagillion ways your could be doing this of course.
I assume the reports are just too extensive, varied, and different in nature that you can't just put sql and styling building block in the db?
Edit based on op's comments:
Ah, gotcha. Well, I don't know how much time you have, but as much as you push everything into some sort of factory, you have better options you'll later. I'm going to give you some thoughts that will hopefully help, from similar things I've done. Each step is an improvement in itself, but also a baby step to really separating your report logic from this shell code. Further, I can see you already know what you're doing and I'm sure know some of what I'll say below, but I don't know what you know, and it will be helpful for others.
First, pull out any and every bit of information from code to db (if you haven't already), and you'll add more db fields (and a table or two) as you improve your setup.
You might know about it already, but I'll mention it for others, to check out the strategy pattern I reference above. You can have the custom logic of each "report function" actually be in the constructor of your various strategy classes. They would all inherit from your base ReportGenerator (or sport a common IReportGenerator interface). They can and should share the same constructor; varying report parameters would be handled by a parameter of type dictionary. Each class's constructor implementation would know the types of the variables is needs (from db configuration), and would cast/use them accordingly.
Next step might be to really get rid of your select statement in your factory, using reflection. You'd have to have the name of the class as part of your reports configuration data in the db (and have a common constructor).
At this point, the way to add a new report is pretty clean, even though you've got to add a new class each time. That good. It fulfills the single responsibility and open-closed principals.
Now, there's just the final step of removing the classes from your app, so they can be added/edited on the fly. Check out MEF. This is what it's made for. Some things you might find on the internet that you probably shouldn't use are CodeDom (great when there was nothing else, but MEF is better) and the compilation-as-a-service features coming in .NET 5. MEF is the way to go.
Assuming that all reports implement IReport, you can do it using Func<IReport>, like this:
IDictionary<string,Func<IReport>> dictToReport = new Dictionary {
{"ReportA", () => CreateReportAReport("ReportA's Title") }
, {"ReportB", () => CreateReportBReport("ReportB's Title") }
, ...
};
You can then replace the switch with this code:
var myReport = dictToReport[Request.QueryString["Report"]]();
I think is better re-design this code and convert it into some database table ("Reports") to keep there the list of reports and ID of each report.
That's it.
To do this with a Dictionary<string, string> you would simply build one up as a static cache in the containing type
public class Container {
private static Dictionary<string, Func<Report>> ReportMap =
new Dictionary<string, Func<Report>>();
static Container() {
ReportMap["ReportA"] = () => CreateReportAReport("ReportA's Title");
ReportMap["ReportB"] = () => CreateReportBReport("ReportB's Title");
// etc ...
}
}
Now that the map is built you simply do a lookup in the function instead of a switch
Func<Report> func;
if (!ReportMap.TryGetValue(Request.QueryString["Report"), out func)) {
// Handle it not being present
throw new Exception(..);
}
Report report = func();
So WPF doesn't support standard sorting or filtering behavior for views of CompositeCollections, so what would be a best practice for solving this problem.
There are two or more object collections of different types. You want to combine them into a single sortable and filterable collection (withing having to manually implement sort or filter).
One of the approaches I've considered is to create a new object collection with only a few core properties, including the ones that I would want the collection sorted on, and an object instance of each type.
class MyCompositeObject
{
enum ObjectType;
DateTime CreatedDate;
string SomeAttribute;
myObjectType1 Obj1;
myObjectType2 Obj2;
{
class MyCompositeObjects : List<MyCompositeObject> { }
And then loop through my two object collections to build the new composite collection. Obviously this is a bit of a brute force method, but it would work. I'd get all the default view sorting and filtering behavior on my new composite object collection, and I'd be able to put a data template on it to display my list items properly depending on which type is actually stored in that composite item.
What suggestions are there for doing this in a more elegant way?
I'm not yet very familiar with WPF but I see this as a question about sorting and filtering List<T> collections.
(withing having to manually implement sort or filter)
Would you reconsider implementing your own sort or filter functions? In my experience it is easy to use. The examples below use an anonymous delegate but you could easily define your own method or a class to implement a complex sort or filter. Such a class could even have properties to configure and change the sort and filter dynamically.
Use List<T>.Sort(Comparison<T> comparison) with your custom compare function:
// Sort according to the value of SomeAttribute
List<MyCompositeObject> myList = ...;
myList.Sort(delegate(MyCompositeObject a, MyCompositeObject b)
{
// return -1 if a < b
// return 0 if a == b
// return 1 if a > b
return a.SomeAttribute.CompareTo(b.SomeAttribute);
};
A similar approach for getting a sub-collection of items from the list.
Use List<T>.FindAll(Predicate<T> match) with your custom filter function:
// Select all objects where myObjectType1 and myObjectType2 are not null
myList.FindAll(delegate(MyCompositeObject a)
{
// return true to include 'a' in the sub-collection
return (a.myObjectType1 != null) && (a.myObjectType2 != null);
}
"Brute force" method you mention is actually ideal solution. Mind you, all objects are in RAM, there is no I/O bottleneck, so you can pretty much sort and filter millions of objects in less than a second on any modern computer.
The most elegant way to work with collections is System.Linq namespace in .NET 3.5
Thanks - I also considered LINQ to
objects, but my concern there is loss
of flexibility for typed data
templates, which I need to display the
objects in my list.
If you can't predict at this moment how people will sort and filter your object collection, then you should look at System.Linq.Expressions namespace to build your lambda expressions on demand during runtime (first you let user to build expression, then compile, run and at the end you use reflection namespace to enumerate through results). It's more tricky to wrap your head around it but invaluable feature, probably (to me definitively) even more ground-breaking feature than LINQ itself.
Update: I found a much more elegant solution:
class MyCompositeObject
{
DateTime CreatedDate;
string SomeAttribute;
Object Obj1;
{
class MyCompositeObjects : List<MyCompositeObject> { }
I found that due to reflection, the specific type stored in Obj1 is resolved at runtime and the type specific DataTemplate is applied as expected!