This question already has answers here:
What does "where" mean in a C# class declaration?
(9 answers)
Closed 8 years ago.
I'm doing some Pluralsight training. The instructor specified several function declarations in an interface, one of which looks like this:
void Add<T>(T entity) where T : class;
So generics are being used, the data type is of type "T", it's declaring a parameter named "entity" which is of type T. What I don't understand if the clause:
"where T : class"
What does that mean?
This is called a generic constraint. It means that the type of T must be a class.
It's ensuring that the generic type T is of type class.
So as an example yourClass.Add<int>(2) would show a compile time error because int is not a class/reference type.
it is a constraint which says your T should be a reference Type.
From MSDN: where T : class
The type argument must be a reference type; this applies also to any
class, interface, delegate, or array type.
Related
This question already has answers here:
What is the <T> in Cast<T>() or List<T> in C#
(2 answers)
Closed 2 years ago.
I'm new into c# and I see a lot of things like System.Span<T>, System.Memory<T>, Span<T>, Memory<T>, System.Collections.Generic.IEnumerable<T> etc. in the C# documentation.
Can somebody please explain what <T> is?
Any help is appreciated.
Check Generic Parameters
In a generic type or method definition, a type parameter is a placeholder for a specific type that a client specifies when they create an instance of the generic type. A generic class, such as GenericList<T> listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type. To use GenericList<T>, client code must declare and instantiate a constructed type by specifying a type argument inside the angle brackets. The type argument for this particular class can be any type recognized by the compiler. Any number of constructed type instances can be created, each one using a different type argument, as follows:
For instance:
GenericList<float> list1 = new GenericList<float>();
GenericList<ExampleClass> list2 = new GenericList<ExampleClass>();
GenericList<ExampleStruct> list3 = new GenericList<ExampleStruct>();
In each of these instances of GenericList, every occurrence of T in the class is substituted at run time with the type argument. By means of this substitution, we have created three separate type-safe and efficient objects using a single class definition. For more information on how this substitution is performed by the CLR
In addition to the above, you can also have constraints about the type that T can be.
This question already has answers here:
What are the differences between Generics in C# and Java... and Templates in C++? [closed]
(13 answers)
Closed 8 years ago.
When I read about generic programming, often, are used this two terms:
parametrized types;
type parameters
Are there difference between them?
In Java, in the following declaration
public class Foo<T> { ... }
Foo is a parameterized type. T is a type parameter.
Using C++ terminology:
A class template corresponds to a parameterised type - it becomes a type once you specify arguments for the parameters.
A type parameter is a parameter of a template, for which the arguments are types.
Generic types are also known as parametized types.
Type parameters refers to the types associated with a generic type. For example, with
Dictionary<T1, T2>
T1 and T2 are the type parameters.
This question already has answers here:
What does "where T : class, new()" mean?
(11 answers)
Closed 9 years ago.
I wonder what is this? This kind of a generic method I think. It has a part with 'where'. What about that? There is also generic classes I've heard. How can I learn these can you recommend an article?
protected T Item<T>() where T : class
{
return GetDataItem() as T ?? default(T);
}
The where clause is called a "generic constraint". In that case, where T: class dictates that T must be a reference type (i.e., not a struct).
More info on generic constraints: http://msdn.microsoft.com/en-us/library/d5x73970.aspx
And generic classes: http://msdn.microsoft.com/en-us/library/sz6zd40f.aspx
Edit
In the snippet you provided, the constraint is needed because otherwise the null-coalescing operator (??) wouldn't make sense, since value types (structs) can't be null.
This question already has answers here:
If A<T1,T2> is a template for actual type, then why is typeof(A<,>) allowed?
(3 answers)
Closed 9 years ago.
I have some confusion with this that arose from messing around with exporting generic types in MEF
I noticed:
new Dictionary<string,bool>().GetType() == typeof(Dictionary<,>)
false
new Dictionary<string,bool>().GetType().GetGenericTypeDefinition() == typeof(Dictionary<,>)
true
Yet Dictionary<,> itself is not considered a ‘type’ as this will actually generate a compile error:
new Dictionary<string,bool> as Dictionary<,>
Type expected
new Dictionary<string,bool> is Dictionary<,>
Type expected
So my question is, is Dictionary<,> actually a type? Does .NET treat generic types differently than non-generic types?
Now in MEF I can export a generic class as
[Export(typeof(MyGenericClass<,>))]
And this would satisfy an import requirement like
[Import]
public MyGenericClass<string, long> Instance { get; set; }
I'm confused about the type-system's rules here
See What exactly is an “open generic type”. What you are referring to is called an unbound generic type and is explained in the same post. An unbound generic type is actually a type, however it can only be used within a typeof() expression. Note: Unlike C# Java allows expressions like List<?>.
Yes, MyType<,> is a type.
It's a "open generic" Type, See What exactly is an "open generic type" in .NET?
This question already has answers here:
How do I use reflection to call a generic method?
(8 answers)
Closed 9 years ago.
The generic Method is...
public void PrintGeneric2<T>(T test) where T : ITest
{
Console.WriteLine("Generic : " + test.myvar);
}
I'm calling this from Main()...
Type t = test2.GetType();
PrintGeneric2<t>(test2);
I get error "CS0246: the type or namespace name 't' could not be found" and "CS1502: best overloaded method match DoSomethingClass.PrintGeneric2< t >(T) has invalid arguments"
this is related to my previous question here: C# : Passing a Generic Object
I've read that the generic type can't be determined at runtime, without the use of reflection or methodinfo, but I'm not very clear on how to do so in this instance.
Thanks if you can enlighten me =)
If you really want to invoke a generic method using a type parameter not known at compile-time, you can write something like:
typeof(YourType)
.GetMethod("PrintGeneric2")
.MakeGenericMethod(t)
.Invoke(instance, new object[] { test2 } );
However, as stated by other responses, Generics might not be the best solution in your case.
Generics offer Compile Time parametric polymorphism. You are trying to use them with a type specified only at Runtime.
Short answer : it won't work and it has no reason to (except with reflection but that is a different beast altogether).
Just call:
PrintGeneric2(test2);
The compiler will infer <t> from what you pass.