Is there ever a reason to use Type parameters over generics, ie:
// this...
void Foo(Type T);
// ...over this.
void Foo<T>();
It seems to me that generics are far more useful in that they provide generic constraints and with C# 4.0, contravarience and covarience, as well as probably some other features I don't know about. It would seem to me that the generic form has all the pluses, and no negatives that the first doesn't also share. So, are there any cases where you'd use the first instead?
Absolutely: when you don't know the type until execution time. For example:
foreach (Type t in someAssembly.GetTypes())
{
Foo(t);
}
Doing that when Foo is generic is painful. It's doable but painful.
It also allows the parameter to be null, which can be helpful in some situations.
Well they really aren't the same at all.
With the second one, you've actually got a class of the compile-time type there (whatever has been passed in by whoever). So you can call specific functions on it (say if it's all of some given interface).
In your first example, you've got an object of class 'Type'. So you'll need to still determine what it is and do a cast to do anything useful with it.
Foo(someVariable.GetType()); // allowed
Foo<someVariable.GetType()>(); // illegal
Related
Up until now, C# inferrence has always worked well for me. I have created a test example to simplify the case.
class Parent
{
public void InferrenceTesting<T>() where T : Parent
{
}
}
class Child : Parent
{
public void Test()
{
//this line gives me a compiler error : The type arguments for method 'Parent.InferrenceTesting<T>()' cannot be inferred from the usage. Try specifying the type arguments explicitly.
this.InferrenceTesting();
}
}
I have read quite a lot on inferrence, but I am clueless as of why this doesn't work.
Inference of generic method type arguments to the method type parameters proceeds by making inferences based on the relationships between the formal arguments and the formal parameters.
Your method has zero formal arguments and zero formal parameters, so no inferences are made.
Note that in particular inferences are never made from generic parameter constraints. Constraints are not part of the signature of a method and inference concerns itself with signatures. Rather, constraints are checked after type inference has succeeded. If you're expecting some sort of inference to be made from your where clause, your expectation is mistaken.
I have read quite a lot on inference, but I am clueless as of why this doesn't work.
You may wish to read my blog articles on type inference if this subject interests you. They may be more accurate than some of the other articles you've read on this subject; I occasionally see misinformation out there. From my current blog:
https://ericlippert.com/category/csharp/type-inference/
And my former Microsoft blog:
https://blogs.msdn.microsoft.com/ericlippert/tag/type-inference/
In particular, see
https://blogs.msdn.microsoft.com/ericlippert/2009/12/10/constraints-are-not-part-of-the-signature/
The comments to that blog are quite interesting. If you've ever wanted to see like a hundred people tell me that I'm wrong, the design is wrong, the implementation is wrong, well, that's the place to go.
There's nothing it can use to infer the type from. You've said that T has to be a type of Parent but since you're not passing a parameter of that type (which the compiler can use to infer the type) you'll have to explicitly name the type.
The compiler has no information to infer from - you need a parameter or some other information to tell the compiler what T should be in order to infer it.
I'm no expert in this, but I think there is nothing to infer from.
The simple fact that this method is declared in a Parent derivate has nothing to do with it.
You need an argument of type T for that method so that the compiler has something from which he can infere what should be used as T.
In your call, T does not need to be either Parent or Child. It can be anything as long as it inherits from Parent.
I have that code:
myDataGrid is an object passed to the method. I know it is type of OvserveableCollection of different types.
All I need is to cast that object to OvserveableCollection<T> (it implements the IEnumerable interface)
//get element's type
Type entryType = (myDataGrid as IEnumerable).AsQueryable().ElementType;
foreach (var item in (IEnumerable<entryType>)myDataGrid)
{}
but the compiler doesn't know the entryType in the loop header. Why ?
You can't use a runtime Type instance as a generic type parameter unless you use reflection (MakeGenericMethod() / MakeGenericType()). However I doubt it would help anyway! In this scenario, either use the non-generic IEnumerable (no <T>) API, or perhaps cast to a known interface/subclass, or use dynamic as a last resort duck-typing.
You can also use MakeGenericMethod() etc, but that is more involved and almost certainly slower.
For example:
foreach(object item in (IEnumerable)myDataGrid)
{
// tada!
}
Another trick can be to use dynamic to invoke the generic code:
public void Iterate<T>(IEnumerable<T> data)
{
foreach(T item in data) {...}
}
...
dynamic evil = myDataGrid;
Iterate(evil);
You're trying to use a Type variable as a type argument for a generic type. Generics don't work that way - you have to use a compile-time type as the type argument. (That compile-time type can be a type parameter itself, if you're doing this in a generic method.)
It's hard to know how to advise you to change the code without knowing more about your requirements though - what do you need to do with the items?
You can't cast to a "runtime type"... in order to "write" the instructions which actually implement that cast, the compiler requires the Type... which really just means that the Type must be known at COMPILE time.
The ONLY way I've ever found around this limitation was code-generator (of one sort or another) to "manually" generate the IL instructions to perform the cast. It's hard to know what to recommend unless we know a lot about your actual requirements (and constraints).
Cheers. Keith.
In C#, how can I find out if a Type can be instantiated? I am trying to avoid an Activator.CreateInstance exception.
My current method is type.IsClass && !type.IsInterface, but I am worried this could fail on abstract classes, etc. I also considered checking type.TypeInitializer == null, but I am not sure if that is foolproof either.
What is the simplest/most efficient way possible to find out if a Type is instantiable?
Consider IsAbstract . It would handle abstract as well as static class. You may also want to check on IsInterface
There are many other traps. It could have a constructor that is private or protected. Or it might not have a default constructor, only constructors that take certain argument types. If you have to worry about that then you are surely using Activator.CreateInstance() when it should not be used. Just arbitrarily constructing objects can only create havoc, you have no idea what kind of side effects they may have. Avoid the "FormatDisk" class.
An exception is your friend, it tells you that your assumptions were wrong. Never intentionally stop the .NET framework from being helpful.
I have a question. In the framework, that was largely written before the generics came, you often see a function with lots of overloads to do something with different types.
a)
Parse(int data)
Parse(long data)
Parse(string data)
..etc
That seems to be to be ok as it helps keeping code small for each method and so. On the other hand, now with generics you can do the following:
b)
Parse<T>(T data)
and then have some kind of ifs/switch statements with typeof() to try to infer what the types are and what to do with them.
What is best practise? Or what are the ideias that'd help me choose between a) and b)?
IMHO, if you need if/switch statements, you should better overload. Generics should be used where the implementation does not depend on the concrete type to still reuse it.
So as a general rule:
overload if there will be a separate implementation for each type
use generics if you can have a single implementation that works for all possible types.
Code Smell.
If you have "some kind of if/switch", that is a code smell that just screams polymorphism. It suggests that generics is not the solution to that problem. Generics should be used when the code does not depend on the concrete types you pass into it.
Watch this Google Tech Talks Video: "The Clean Code Talks -- Inheritance, Polymorphism, & Testing". It addresses specifically what you are talking about.
The pattern your describing where the use of generics results in a bunch of ifs/switch statements is an anti-pattern.
One solution to this is to implement a strategy pattern, which allows you to use generics, but at the same time isolating concerns of the Parse method from knowing how to deal with every different case.
Example:
class SomeParser
{
void Parse<T>(ParseStrategy<T> parseStrategy, T data)
{
//do some prep
parseStrategy.Parse(data);
//do something with the result;
}
}
class ParseStrategy<T>
{
abstract void Parse(T data);
}
class StringParser: ParseStrategy<String>
{
override void Parse(String data)
{
//do your String parsing.
}
}
class IntParser: ParseStrategy<int>
{
override void Parse(int data)
{
//do your int parsing.
}
}
//use it like so
[Test]
public void ParseTest()
{
var someParser = new SomeParser();
someParser.Parse(new StringParser(), "WHAT WILL THIS PARSE TO");
}
and then you would be able to pass in any of the strategies you develop. This would allow you to properly isolate your concerns across multiple classes and not violate SRP (single responsibility principle.
One issue here - if you're requiring if/switch statements to make generics work, you probably have a larger problem. In that situation, it is most likely that the generic argument won't work (correctly) for EVERY type, just a fixed set of types you are handling. In that case, you are much better off providing overloads to handle the specific types individually.
This has many advantages:
There is no chance of misuse - you're user cannot pass an invalid argument
There is more clarity in your API - it is very obvious which types are appropriate
Generic methods are more complicated to use, and not as obvious for beginning users
The use of a generic suggests that any type is valid - they really should work on every type
The generic method will likely be slower, performance wise
If your argument CAN work with any type, this becomes less clear. In that case, I'd often still consider including the overloads, plus a generic fallback method for types. This provides a performance boost when you're passing an "expected" type to the method, but you can still work with other, non-expected types.
While there's no one-size-fits-all rule on this, generics should be used when the specific type is irrelevant. That isn't to say that you can't constrain the type, but that specific type doesn't actually matter. In this case, the parsing method is entirely dependent on (and different for) each type. Generics don't seem like a good solution here.
My rule of thumb for this scenario. There is overlap and there are subtleties, but this gets you on the path:
Overloading methods/functions is concerned with handling types, and doesn't make assumptions about interfaces available on the types.
An overloaded function will deal specifically with a type passed to it, and whatever interface it implements. Example printObject(t) may need to extract a property from 't' and print it manually (e.g. print(t.name) or cout << t.name;)
Generics is concerned with handling the interface(s) implemented, but is not concerned about the type of object.
A generic function will handle any type passed to it, but expect a specific interface implemented (e.g. printObject(t) may just call t.toString() on the object, presuming it's implemented)
I'm very excited about the dynamic features in C# (C#4 dynamic keyword - why not?), especially because in certain Library parts of my code I use a lot of reflection.
My question is twofold:
1. does "dynamic" replace Generics, as in the case below?
Generics method:
public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) {
//test object is not null, regardless of its Type
if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) {
//do something
}
}
dynamic method(??):
public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) {
//test object is not null, regardless of its Type?? but how?
if (ObjToTest != null) {
//do something
}
}
2. does "dynamic" now allow for methods to return Anonymous types, as in the case below?:
public static List<dynamic> ReturnAnonymousType() {
return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList();
}
cool, cheers
EDIT:
Having thought through my question a little more, and in light of the answers, I see I completely messed up the main generic/dynamic question. They are indeed completely different. So yeah, thanks for all the info.
What about point 2 though?
dynamic might simplify a limited number of reflection scenarios (where you know the member-name up front, but there is no interface) - in particular, it might help with generic operators (although other answers exist) - but other than the generic operators trick, there is little crossover with generics.
Generics allow you to know (at compile time) about the type you are working with - conversely, dynamic doesn't care about the type.
In particular - generics allow you to specify and prove a number of conditions about a type - i.e. it might implement some interface, or have a public parameterless constructor. dynamic doesn't help with either: it doesn't support interfaces, and worse than simply not caring about interfaces, it means that we can't even see explicit interface implementations with dynamic.
Additionally, dynamic is really a special case of object, so boxing comes into play, but with a vengence.
In reality, you should limit your use of dynamic to a few cases:
COM interop
DLR interop
maybe some light duck typing
maybe some generic operators
For all other cases, generics and regular C# are the way to go.
To answer your question. No.
Generics gives you "algorithm reuse" - you write code independent of a data Type. the dynamic keyword doesn't do anything related to this. I define List<T> and then i can use it for List of strings, ints, etc...
Type safety: The whole compile time checking debate. Dynamic variables will not alert you with compile time warnings/errors in case you make a mistake they will just blow up at runtime if the method you attempt to invoke is missing. Static vs Dynamic typing debate
Performance : Generics improves the performance for algorithms/code using Value types by a significant order of magnitude. It prevents the whole boxing-unboxing cycle that cost us pre-Generics. Dynamic doesn't do anything for this too.
What the dynamic keyword would give you is
simpler code (when you are interoperating with Excel lets say..) You don't need to specify the name of the classes or the object model. If you invoke the right methods, the runtime will take care of invoking that method if it exists in the object at that time. The compiler lets you get away even if the method is not defined. However it implies that this will be slower than making a compiler-verified/static-typed method call since the CLR would have to perform checks before making a dynamic var field/method invoke.
The dynamic variable can hold different types of objects at different points of time - You're not bound to a specific family or type of objects.
To answer your first question, generics are resolved compile time, dynamic types at runtime. So there is a definite difference in type safety and speed.
Dynamic classes and Generics are completely different concepts. With generics you define types at compile time. They don't change, they are not dynamic. You just put a "placeholder" to some class or method to make the calling code define the type.
Dynamic methods are defined at runtime. You don't have compile-time type safety there. The dynamic class is similar as if you have object references and call methods by its string names using reflection.
Answer to the second question: You can return anonymous types in C# 3.0. Cast the type to object, return it and use reflection to access it's members. The dynamic keyword is just syntactic sugar for that.