Find all static references to a class by code c# - c#

I search for a way to display all static occurances of classes (similiar to the Visual Studio functionality: find all references).
It should only be by code and not manually.
I want to
Only list classes with a specific attribute
List all classes which have static references to it (find table bindings to data classes)
My first step is to list all Types which i'm interested in:
var result = from t in assembly.GetTypes()
where t.IsDefined(typeof(TAttribute), inherit)
select t;
return result.ToList();
I'm having problems with the second step.
I know how to find Properties... from a class. But how is it possible to go the other way round, and find all usages of a class?

You can not find static references using reflection, it's something that AST may know about. For this you may want to use: Roslyn (Compiler as a Service), that let's you compile, and investigate AST.

You can't find references in method bodies using reflection but you can find fields, properties and methods parameters/return values.
You already know how to list all types, now for each type:
Type.GetProperties returns an array of PropertyInfo, you can check if `PropertyInfo.ProeprtType' is in the list of types you care about.
Same goes for fields with Type.GetFields
For methods you call Type.GetMethods, this returns an array of MethodInfo objects, to get the return type you check MethodInfo.ReturnType and for the parameters call MethodInfo.GetParameters and ParameterInfo.ParameterType
That's only leaves local variables defined inside method bodies and those cannot be accessed with reflections

Related

Get the classes from another project [duplicate]

Is there a better (more performant or nicer code ;) way to find all derived Types of a Type?
Currently im using something like:
get all types in used Assemblies
check my type with all those types if it is 'IsAssignable'
I was wondering if theres a better way todo this?
I once used this Linq-method to get all types inheriting from a base type B:
var listOfBs = (
from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
// alternative: from domainAssembly in domainAssembly.GetExportedTypes()
from type in domainAssembly.GetTypes()
where typeof(B).IsAssignableFrom(type)
// alternative: && type != typeof(B)
// alternative: && ! type.IsAbstract
// alternative: where type.IsSubclassOf(typeof(B))
select type).ToArray();
EDIT: As this still seems to get more rep (thus more views), let me add a fluent version and some more details:
var listOfBs = AppDomain.CurrentDomain.GetAssemblies()
// alternative: .GetExportedTypes()
.SelectMany(domainAssembly => domainAssembly.GetTypes())
.Where(type => typeof(B).IsAssignableFrom(type)
// alternative: => type.IsSubclassOf(typeof(B))
// alternative: && type != typeof(B)
// alternative: && ! type.IsAbstract
).ToArray();
Details:
As the above-mentioned link states, this method uses Reflection on each call. So when using the method repeatedly for the same type,
one could probably make it much more efficient by loading it once.
As Anton suggests, maybe you could (micro)optimize it using domainAssembly.GetExportedTypes()
to retrieve only publicly visible types (if that's all you need).
As Noldorin mentions, Type.IsAssignable will also get the original (non-derived) type. (Type.IsSubclassOf will not, but Type.IsSubclassOf will not work if the base type is an interface). But of course, one can exclude the original base class: && type != typeof(B).
One may want/need to check for a concrete implemented class, i.e. ignore abstract classes: && ! assemblyType.IsAbstract. (Note that all interfaces are considered abstract, see MSDN.)
FWIW: as Jon Skeet suggested in a similar question: "it is trickier if you need to handle generics".
A quick search returns some suggestions, but there are probably more, and I did not check them (e.g. for correctness):
Get all types implementing specific open generic type
Get all implementations types of a generic interface
Getting all types that implement an interface
I'm pretty sure the method you suggested is going to be the easier way to find all derived types. Parent classes don't store any information about what their sub-classes are (it would be quite silly if they did), which means there's no avoiding a search through all the types here.
Only recommendation is to use the Type.IsSubclassOf method instead of Type.IsAssignable in order to check whether a particular type is derived from another. Still, perhaps there is a reason you need to use Type.IsAssignable (it works with interfaces, for example).
The only optimization you can squeeze out of this is to use Assembly.GetExportedTypes() to retrieve only publicly visible types if that's the case. Other than that, there's no way to speed things up. LINQ may help with readability side of things, but not performance-wise.
You can do some short-circuiting to avoid unnecessary calls to IsAssignableFrom which is, according to Reflector, quite expensive one, by first testing whether the type in question is of required "class". That is, you're searching for classes only, there's no point in testing enums or arrays for "assignability".
I think there is no better or direct way.
Better: Use IsSubclassOf instead of IsAssignable.
Asuming baseType contains a System.Type object that you want to check against and matchType contains a System.Type object with the type of your current iteration (through a foreach-loop or whatever):
If you want to check wheather matchType is derived from the class represented by baseType I'd use
matchType.IsSubclassOf(baseType)
And if you want to check wheather matchType implements the interface represented by baseType I'd use
matchType.GetInterface(baseType.ToString(), false) != null
Of course I'd store baseType.ToString() as a global variable so I wouldn't need to call it all the time. And since you probably would need this in a context where you have a lot of types, you could also consider using the System.Threading.Tasks.Parallel.ForEach-Loop to iterate through all your types...
If you're just interested in browsing, then .NET Reflector has the ability to do this. However, it isn't something that's really feasible. Would you want all types that are in the currently loaded assemblies? Assemblies referenced by the executing assembly? There are many different ways to obtain a list of Types, and writing something that would account for (and provide options for) would be a pretty big cost with relatively low benefit.
What are you trying to do? There's likely a better (or at least more efficient) way to accomplish it.
I ended up using the code that the top answer gave. Only thing is I wanted the code to be more readable so I wrote basically the same thing but like this instead:
var derived_types = new List<Type>();
foreach (var domain_assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var assembly_types = domain_assembly.GetTypes()
.Where(type => type.IsSubclassOf(typeof(MyType)) && !type.IsAbstract);
derived_types.AddRange(assembly_types);
}
In my case I used type.IsSubClassOf(MyType) because I only wanted derived types excluding the base class like mentioned above. I also needed the derived types not to be abstract (!type.IsAbstract) so I am also excluding derived abstract classes.
Just create a static dictionary of derived types on start and do lookup with that.
Eg. public static Dictionay<Type, Type[]> DerivedTypes { get;set; }
where Type is any type you want to include in the search
and Type[] is a list of derived types.
Fill the dictionary up when app starts and use it during the whole life of the app.

List<dynamic> elements have fields but I cannot access them. Why?

I need to loop over a List<dynamic> objects.
The list's objects all have values, but for some reason, I am not able to access any of the dynamic object fields. Below is a screenshot of my debug window:
There you can see the object contains fields (such Alias, Id, Name, etc).
I tried both casting it to a IDictionary<string, object> and ExpandoObject, to no avail. I did not face such a thing before: failing to access existing fields in a dynamic object when they exist.
What is wrong here?
The code is throwing a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException with a message stating {"'object' does not contain a definition for 'Name'"}.
The list was created adding anonymously-typed objects, like this:
return new List<dynamic>(fields.Select(field => new
{
Id = field.Id,
Alias = field.Alias,
Name = field.Name,
Type = field.Type,
Value = field.Value,
SortOrder = field.SortOrder
}));
where fields is an ICollection<Field>, a strongly-typed collection.
The telling part is the exception:
{"'object' does not contain a definition for 'Name'"}.
This indicates that the runtime binder was not actually capable of accessing the type you're passing in dynamic (since dynamic does actually enforce visibility rules).
The most likely cause of this is that you're creating the anonymous type in a different assembly from the one where you're subsequently reading it - since anonymous types are declared internal, the consuming assembly cannot access it, causing the error message above.
Contrast with the usual case of runtime binder exceptions:
'<>f__AnonymousType0< string >' does not contain a definition for 'Name'
EDIT:
A possible solution to the problem is to use the InternalsVisibleToAttribute on the assembly containing the anonymous type. However, this is code smell - just like any other use of InternalsVisibleToAttribute or internal itself.
A better way would be to make sure you don't actually pass anonymous types over assembly boundaries - after all, they shouldn't even be used outside of the method they originated from; the fact that they are is basically an implementation detail of .NET - they didn't have another way to do the same thing. This could change in future versions, making the InternalsVisibleToAttribute solution doubly unreliable.
The way your code is using dynamic suggests that your team has flawed assumptions about how dynamic works and how it's supposed to be used. Note how the actual runtime type of List<dynamic> is actually List<object>. The same goes for arguments of type dynamic (which are again just object, albeit marked with DynamicAttribute). And in fact, that really is what dynamic is - it's a way to handle runtime dynamic dispatch - it's not a property of the type or anything, it's just the way you actually invoke whatever you're trying to invoke. For C#, dynamic allows you to skip most of the compiler checks when working with those dynamic types, and it generates some code to handle the dispatch for you automatically, but all of that only happens inside the method where you actually use the dynamic keyword - if you used List<object>, the end result would be exactly the same.
In your code, there's no reason not to use simple static types. Dynamic typing doesn't really give you any benefits, apart from the effort to code the types themselves. If your co-workers don't like that, well, they should present a better solution - the problem is quite obvious, and it's something you need to deal with.
Much worse, it explicitly hides all context, all the type information. That's not something you want in an API, internal or not! If you want to hide the concrete types being used, why not - but you should still expose an interface instead. I suspect this is the reason why anonymous types can't implement interfaces - it would encourage you to go entirely the wrong way.

Is it possible to declare an anonymous type in C# with a variable/dynamic set of fields?

In C#, I would like to figure out if it's possible to declare an anonymous type where the fields are not known until run-time.
For example, if I have a List of key/value pairs, can I declare an anonymous type based on the contents of that list? The specific case I'm working with is passing parameters to Dapper, where I don't know ahead of time how many parameters I will have.
List<Tuple<string, string>> paramList = new List<Tuple<string, string>>() {
new Tuple<string, string>("key1", "value1"),
new Tuple<string, string>("key2", "value2")
...
};
I'd like to convert this List (or an equivalent Map) into an anonymous type that I can pass to Dapper as query parameters. So ideally, the above list would wind up looking like this, if defined as an anonymous type:
new { key1=value1, key2=value2, ... }
I've seen several questions on StackOverflow asking about extending anonymous types after they are declared ("extendo objects"), or declaring arbitrary fields on an object after it's created, but I don't need to do that... I just need to declare the types dynamically up-front once. My suspicion is that it will require some fancy reflection, if it's possible at all.
My understanding is that the compiler defines a type for anonymous classes under the hood at compile-time, so if the fields of that class are not available until run-time, I might be out of luck. My use case may in fact be no different in actuality than using an "extendo object" to define arbitrary fields, whenever.
Alternatively, if anyone knows of a better way to pass query parameters to Dapper (rather than declaring an anonymous class), I would love to hear about that as well.
Thanks!
UPDATE
Sorry for the delay in getting back to this one! These answers were all great, I wish I could give points to everyone. I ended up using jbtule's solution (with edit by Sam Saffron), passing IDynamicParameters to Dapper, so I felt I had to give the answer to him. The other answers were also good, and answered specific questions that I had asked. I really appreciate everyone's time on this!
Dapper's creators were very aware of this problem. This kind of functionality is really needed for INSERT and UPDATE helpers.
The Query, Execute and QueryMultiple methods take in a dynamic parameter. This can either be an anonymous type, a concrete type or an object that implements IDynamicParameters.
public interface IDynamicParameters
{
void AddParameters(IDbCommand command, Identity identity);
}
This interface is very handy, AddParameters is called just before running any SQL. Not only does this give you rich control over the parameters sent to SQL. It allows you to hook up DB specific DbParameters, since you have access to the command (you can cast it to the db specific one). This allows for support of Table Values Parameters and so on.
Dapper contains an implementation of this interface that can be used for your purposes called DynamicParameters. This allows you to both concatenated anonymous parameter bags and add specific values.
You can use the method AddDynamicParams to append an anonymous type.
var p = new DynamicParameters();
p.AddDynamicParams(new{a = "1"});
p.AddDynamicParams(new{b = "2", c = "3"});
p.Add("d", "4")
var r = cnn.Query("select #a a, #b b, #c c, #d d", p);
// r.a == 1, r.b == 2, r.c == 3, r.d == 4
In C#, I would like to figure out if it's possible to declare an anonymous type where the fields are not known until run-time.
Anonymous types are generated by the compiler. You want to know if the compiler will generate you a compiler-generated type with field types not known to the compiler. Clearly it cannot do so; as you correctly surmise, you are out of luck.
I've seen several questions on StackOverflow asking about extending anonymous types after they are declared ("extendo objects")
We usually call those "expando" objects.
If what you want to do is make an expando object based on a dictionary of key-value pairs, then use the ExpandoObject class to do that. See this MSDN article for details:
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx
If what you want to do is generate a bona-fide .NET class at runtime, you can do that too. As you correctly note, you need some fancy reflection to do so. What you want to do is make a collectible assembly (so-called because unlike a normal assembly, you generate it at runtime and the garbage collector will clean it up when you are done with it.)
See http://msdn.microsoft.com/en-us/library/dd554932.aspx for details on how to make a collectible assembly and emit a type into it using a TypeBuilder.
You can't use an anonymous type. Anonymous types are generated by the compiler rather than at run-time. You could certainly use dynamic though:
dynamic dynamicObj = new ExpandoObject();
var objAsDict = (IDictionary<String, Object>)dynamicObj;
foreach(var item in paramList)
{
objAsDict.Add(item.Item1, item.Item2);
}
You can then use dynamicObj as a regular object:
Console.WriteLine(dynamicObj.key1); // would output "value1"

What is equivalent to Microsoft.VisualBasic.Collection in c#?

I have a method which takes a stored procedure name and a Microsoft.VisualBasic.Collection? I am referencing a vb project in which I have to pass in a collection to this method, but the current project I am in is in c#, so I am unclear what I can pass into the method?
Here is the vb call:
public void CallStoredProc(string spName, Microsoft.VisualBasic.Collection params);
In my c# app, I need to call this an pass in the appropriate c# object to params.
One option is to simply use the Collection type directly from C#. This is a standard type in the Microsoft.VisualBasic.dll assembly and can be used from any .Net language.
The closest collection in the standard BCL though is Hashtable. Converting between Hashtable and Collection should be fairly straight forward
For example
using VBCollection = Microsoft.VisualBasic.Collection;
...
public static VBCollection ToVBCollection(this Hashtable table) {
var collection = new VBCollection();
foreach (var pair in table) {
// Note: The Add method in collection takes value then key.
collection.Add(pair.Value, pair.Key);
}
return collection;
}
Note: This is not a direct mapping though. The Collection type supports a number of operations which Hashtable does not like: before and after values, index by number or key, etc ... My approach would be to use one type consistently throughout the application and change either the C# or VB project appropriately
Unless you can change the method, so that it takes ICollection, IEnumerable or their generic variants, you have to pass an instance of Microsoft.VisualBasic.Collection to that method.
From the point of view of C#, Microsoft.VisualBasic.Collection is just a class and you can work with it as with any other class, i.e. instance it:
new Microsoft.VisualBasic.Collection()
Of course, you have to reference the assembly Microsoft.VisualBasic.dll in your project.
There is no such thing as a "C# object", or a "VisualBasic.net object" - it is all .net, so you can simply include a reference to Microsoft.VisualBasic.dll and use that Microsoft.VisualBasic.Collection.
C# devs often frown upon Microsoft.VisualBasic.dll because of the name, but you won't be eaten by Velociraptors if you use it since .net is properly and fully language-independent.

Get all derived types of a type

Is there a better (more performant or nicer code ;) way to find all derived Types of a Type?
Currently im using something like:
get all types in used Assemblies
check my type with all those types if it is 'IsAssignable'
I was wondering if theres a better way todo this?
I once used this Linq-method to get all types inheriting from a base type B:
var listOfBs = (
from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
// alternative: from domainAssembly in domainAssembly.GetExportedTypes()
from type in domainAssembly.GetTypes()
where typeof(B).IsAssignableFrom(type)
// alternative: && type != typeof(B)
// alternative: && ! type.IsAbstract
// alternative: where type.IsSubclassOf(typeof(B))
select type).ToArray();
EDIT: As this still seems to get more rep (thus more views), let me add a fluent version and some more details:
var listOfBs = AppDomain.CurrentDomain.GetAssemblies()
// alternative: .GetExportedTypes()
.SelectMany(domainAssembly => domainAssembly.GetTypes())
.Where(type => typeof(B).IsAssignableFrom(type)
// alternative: => type.IsSubclassOf(typeof(B))
// alternative: && type != typeof(B)
// alternative: && ! type.IsAbstract
).ToArray();
Details:
As the above-mentioned link states, this method uses Reflection on each call. So when using the method repeatedly for the same type,
one could probably make it much more efficient by loading it once.
As Anton suggests, maybe you could (micro)optimize it using domainAssembly.GetExportedTypes()
to retrieve only publicly visible types (if that's all you need).
As Noldorin mentions, Type.IsAssignable will also get the original (non-derived) type. (Type.IsSubclassOf will not, but Type.IsSubclassOf will not work if the base type is an interface). But of course, one can exclude the original base class: && type != typeof(B).
One may want/need to check for a concrete implemented class, i.e. ignore abstract classes: && ! assemblyType.IsAbstract. (Note that all interfaces are considered abstract, see MSDN.)
FWIW: as Jon Skeet suggested in a similar question: "it is trickier if you need to handle generics".
A quick search returns some suggestions, but there are probably more, and I did not check them (e.g. for correctness):
Get all types implementing specific open generic type
Get all implementations types of a generic interface
Getting all types that implement an interface
I'm pretty sure the method you suggested is going to be the easier way to find all derived types. Parent classes don't store any information about what their sub-classes are (it would be quite silly if they did), which means there's no avoiding a search through all the types here.
Only recommendation is to use the Type.IsSubclassOf method instead of Type.IsAssignable in order to check whether a particular type is derived from another. Still, perhaps there is a reason you need to use Type.IsAssignable (it works with interfaces, for example).
The only optimization you can squeeze out of this is to use Assembly.GetExportedTypes() to retrieve only publicly visible types if that's the case. Other than that, there's no way to speed things up. LINQ may help with readability side of things, but not performance-wise.
You can do some short-circuiting to avoid unnecessary calls to IsAssignableFrom which is, according to Reflector, quite expensive one, by first testing whether the type in question is of required "class". That is, you're searching for classes only, there's no point in testing enums or arrays for "assignability".
I think there is no better or direct way.
Better: Use IsSubclassOf instead of IsAssignable.
Asuming baseType contains a System.Type object that you want to check against and matchType contains a System.Type object with the type of your current iteration (through a foreach-loop or whatever):
If you want to check wheather matchType is derived from the class represented by baseType I'd use
matchType.IsSubclassOf(baseType)
And if you want to check wheather matchType implements the interface represented by baseType I'd use
matchType.GetInterface(baseType.ToString(), false) != null
Of course I'd store baseType.ToString() as a global variable so I wouldn't need to call it all the time. And since you probably would need this in a context where you have a lot of types, you could also consider using the System.Threading.Tasks.Parallel.ForEach-Loop to iterate through all your types...
If you're just interested in browsing, then .NET Reflector has the ability to do this. However, it isn't something that's really feasible. Would you want all types that are in the currently loaded assemblies? Assemblies referenced by the executing assembly? There are many different ways to obtain a list of Types, and writing something that would account for (and provide options for) would be a pretty big cost with relatively low benefit.
What are you trying to do? There's likely a better (or at least more efficient) way to accomplish it.
I ended up using the code that the top answer gave. Only thing is I wanted the code to be more readable so I wrote basically the same thing but like this instead:
var derived_types = new List<Type>();
foreach (var domain_assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var assembly_types = domain_assembly.GetTypes()
.Where(type => type.IsSubclassOf(typeof(MyType)) && !type.IsAbstract);
derived_types.AddRange(assembly_types);
}
In my case I used type.IsSubClassOf(MyType) because I only wanted derived types excluding the base class like mentioned above. I also needed the derived types not to be abstract (!type.IsAbstract) so I am also excluding derived abstract classes.
Just create a static dictionary of derived types on start and do lookup with that.
Eg. public static Dictionay<Type, Type[]> DerivedTypes { get;set; }
where Type is any type you want to include in the search
and Type[] is a list of derived types.
Fill the dictionary up when app starts and use it during the whole life of the app.

Categories

Resources