When you get Type of the variable you can check its name:
if (my_type.Name=="Int32")
however it would more elegant to write
if (my_type.Name==TypeNames.Int32)
to avoid typos. I can define such class on my own, but maybe there is already definition somewhere?
If yes, where?
Note: please avoid wondering "why would you like to get type of the variable in the first place", "it is better to use 'is'" and alike. Thank you very much!
Edit: meanwhile, I jumped into the conclusion it would be enough to ignore the type of the object (my_type variable) and check the object instead. In other words the my_type is not necessary. I forgot about null case :-( Less code, more sleep, that's what I need ;-)
Try the following
typeof(Int32).Name
If you want to compare types though doing so by name is not the best solution as it will be wrong in many cases. It's more correct to compare the types directly.
if ( m_type == typeof(Int32) ) {
...
}
The type names are not defined anywhere in a class. They are generated at runtime by the CLR (by a call to the external ConstructName function) using reflection.
Using the suggestion of JaredPar will do the job.
Related
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Casting: (NewType) vs. Object as NewType
In C#, why ever cast reference types when you can use "as"?
Casting can generate exceptions whereas "as" will evaulate to null if the casting fails.
Wouldn't "as" be easier to use with reference types in all cases?
eg:
MyObject as DataGridView
rather than,
(DataGridView)MyObject
Consider the following alternatives:
Foo(someObj as SomeClass);
and:
Foo((SomeClass)someObj);
Due to someObj being of the wrong type, the first version passes null to Foo. Some time later, this results in a NullReferenceException being thrown. How much later? Depends on what Foo does. It might store the null in a field, and then minutes later it's accessed by some code that expects it to be non-null.
But with the second version, you find the problem immediately.
Why make it harder to fix bugs?
Update
The OP asked in a comment: isn't is easier to use as and then check for null in an if statement?
If the null is unexpected and is evidence of a bug in the caller, you could say:
SomeClass c = someObj as SomeClass;
if (c == null)
{
// hmm...
}
What do you do in that if-block? There are two general solutions. One is to throw an exception, so it is the caller's responsibility to deal with their mistake. In which case it is definitely simpler to write:
SomeClass c = (SomeClass)someObj;
It simply saves you writing the if/throw logic by hand.
There is another alternative though. If you have a "stock" implementation of SomeClass that you are happy to use where nothing better is available (maybe it has methods that do nothing, or return "empty" values, etc.) then you could do this:
SomeClass c = (someObj as SomeClass) ?? _stockImpl;
This will ensure that c is never null. But is that really better? What if the caller has a bug; don't you want to help find bugs? By swapping in a default object, you disguise the bug. That sounds like an attractive idea until you waste a week of your life trying to track down a bug.
(In a way this mimics the behaviour of Objective-C, in which any attempt to use a null reference will never throw; it just silently does nothing.)
operator 'as' work with reference types only.
Sometimes, you want the exception to be thrown. Sometimes, you want to try to convert and nulls are OK. As already stated, as will not work with value types.
One definite reason is that the object is, or could be (when writing a generic method, you may not know at coding-time) being cast to a value type, in which case as isn't allowed.
One more dubious reason is that you already know that the object is of the type in question. Just how dubious depends on how you already know that. In the following case:
if(obj is MyType)
DoMyTypeStuff((MyType)obj);
else
DoMoreGeneralStuff(obj);
It's hard to justify using as here, as the only thing it really does is add a redundant check (maybe it'll be optimised away, maybe it won't). At the other extreme, if you are half-way to a trance state with the amount of information you've got in you're brain's paged-in memory and on the basis of that you are pretty sure that the object must be of the type in question, maybe it's better to add in the check.
Another good reason is that the difference between being of the wrong type and being null gets hidden by as. If it's reasonable to be passing in a string to a given method, including a null string, but it's not reasonable to pass in an int, then val as string has just made the incorrect usage look like a completely different correct usage, and you've just made the bug harder to find and potentially more damaging.
Finally, maybe if you don't know the type of the object, the calling code should. If the calling code has called yours incorrectly, they should receive an exception. To either allow the InvalidCastException to pass back, or to catch it and throw an InvalidArgument exception or similar is a reasonable and clear means of doing so.
If, when you write the code to make the cast, you are sure that the cast should work, you should use (DataGridView)MyObject. This way, if the cast fails in the future, your assumption about the type of MyObject will cause an invalid cast exception at the point where you make the cast, instead of a null reference exception at some point later.
If you do want to handle the case where MyObject is not a DataGridView, then use as, and presumably check for it being null before doing anything with it.
tl;dr If your code assumes something, and that assumption is wrong at run-time, the code should throw an exception.
From MSDN (as (C# reference)):
the as operator only performs reference conversions and boxing conversions. The as operator cannot perform other conversions, such as user-defined conversions, which should instead be performed using cast expressions.
Taking into consideration all of the comments, we came across this just the other day and wondered why you would do a direct cast over using the keyword as. What if you want the cast to fail? This is sometimes the desirable effect you want from a cast if you're casting from a null object. You then push the exception up the call stack.
So, if you want something to fail, use a direct cast, if you're okay with it not failing, use the as keyword.
As is faster and doesn't throw exceptions. Therefore it is generally preferred. Reasons to use casts include:
Using as, you can only assign types that are lower in the inheritance tree to ones that are higher. For example:
object o = "abc" as object;
DataGridView d = "abc" as DataGridView // doesn't do anything
DataGridView could create a custom cast that does allow this. Casts are defined on the target type and therefore allow everything, as long as it's defined.
Another problem with as is that it doesn't always work. Consider this method:
IEnumerable<T> GetList<T>(T item)
{
(from ... select) as IEnumerable<T>
}
This code fails because T could also be a Value Type. You can't use as on those because they can never be null. This means you'll have to put a constraint on T, while it is actually unnecesary. If you don't know whether you're going to have a reference type or not, you can never use as.
Of course, you should always check for null when you use the as keyword. Don't assume no exceptions will be thrown just becase the keyword doesn't throw any. Don't put a Try {} Catch(NullReferenceException){} around it, that't unneccesary and bloat. Just assign the value to a variable and check for null before you use it. Never use it inline in a method call.
What is the design decision to lean towards not returning an anonymous types from a method?
You can return an instance of an anonymous type from a method - but because you can't name it, you can't declare exactly what the method will return, so you'd have to declare that it returns just object. That means the caller won't have statically typed access to the properties etc - although they could still pass the instance around, access it via reflection (or dynamic typing in C# 4).
Personally I would quite like a future version of C# to allow you to write a very brief class declaration which generates the same code (immutable properties, constructor, Equals/GetHashcode/ToString) with a name...
There is one grotty hack to go round it, called casting by example. I wouldn't recommend it though.
Because an anonymous type has no name. Therefore you cannot declare a return type for a method.
Because C# is statically typed language and in a statically typed language the return type of a method needs to be known at compile time and anonymous types have no names.
How can you use your type inside your method if the definition is only in the call of the method ?
It's not javascript.
A lot of answers heere seem to indicatie that it is not possible because of the current syntax and rule. But the question is about changing them. I think it would be possible, but a little complicated and resulting in an awkward (error-prone) syntax. Like
var f() { return new { A = "*", B = 1 }; }
var x = f();
The question is whether this adds sufficient value to the language to make it worth it.
At least up to 3.5, anonymous types are actually resolved at compile time, and this would be impossible (or quite hard) to do with anonymous method signatures.
I'm familiar with using out to pass in a simple data type for manipulation, but I can't seem to figure out how to pass in this Queue<> without causing a compile error. Any ideas?
Code:
Queue<SqlCommand> insertScriptQueue = new Queue<SqlCommand>();
private void UpdateDefaultIndicator(int newDefaultViewID,
out (Queue<SqlCommand>) insertScriptQueue)
UpdateDefaultIndicator(newViewID, out (Queue<SqlCommand>)insertScriptQueue);
You're passing in a reference type. No need to use out.
You shouldn't be initializing an out variable. If you need to modify an in-scope variable, use ref instead.
As Ed points out in his comment, "modify" may not give you the full idea of what's happening here - an out parameter of a reference type will by definition be an initialized object at the end of the function call. As most other answers have pointed out, if you want to pass in an initialized object, ref is the stronger choice.
Queue<SqlCommand> insertScriptQueue;
private void UpdateDefaultIndicator(int newDefaultViewID,
out Queue<SqlCommand> insertScriptQueue){/*body*/}
UpdateDefaultIndicator(newViewID,out insertScriptQueue);
That works fine for me... What error are you getting?
Why do you want a "out" ...here...why dont you return the type instead ? Let method return Queue<> insteasd of void..will that work for you?
The Queue is going to be passed by reference anyway, its not a value type. Just don't use 'out'. UPDATE: Pardon me, I was thinking of 'ref' - but the fact that you're passing a Queue data type in, and not just an unallocated reference, makes me think that you want to be using 'ref' anyway. Except of course that you don't need to use 'ref' because the Queue isn't a value type; its already going to be passed in 'by reference', by default.
make sure that you are assigning insertScriptQueue some kind of value inside of the UpdateDefaultIndicator method
The answer to the original question, by the way, is that you're casting to Queue, and the cast is returning an interim reference. That reference is not assignable, and so is not a legal out parameter. Erich's code implements the fix for this problem.
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.