Generic classes confusion in c# [duplicate] - c#

This question already has answers here:
In C#, What is <T> After a Method Declaration?
(4 answers)
Closed 7 years ago.
What is TProperty in c#?
I saw a code like this:
public abstract class Myclass<T, TProperty> : ....
I know that T is a generic type for the type we are passing. Is TProperty also the same as T.

Anything inside the <> is a generic type indicator. It's name does not make any difference to the compiler, but it should be meaningful for code readability.
Just like in Dictionary<TKey, TValue>.
Of course it has to be unique to it's scope, inclusive of variable names in that scope.
Note that type indicators are not variables, but the Do collide with variable names (Thank you Aravol for your comment on that).

TProperty is a second generic parameter.
Like object parameters on methods, the names have to be unique to distinguish them
Generics can have more than one parameter
According to the C# language spec, any number - see Tuple<T1...T7, TRest> for eaxmple.
By convention, generic parameter names either are or start with a capital "T".

From the description of the class you provide:
public abstract class Myclass<T, TProperty> : ....
It appears the person who created the class intends for an object (T) and an object property (TProperty) to be supplied whenever creating the class.
A best guess would be something like this:
var mine = new Myclass<Generic.List, String>();
It is hard to tell without any more code or the context of how the code is used, though.

Related

Use right Equals method when use generic type in C# [duplicate]

This question already has answers here:
C# Using Equals method in a generic list fails
(3 answers)
5 ways for equality check in .net .. why? and which to use?
(4 answers)
Closed 2 years ago.
I have classes:
public class A : IEquatable<A>
{
...
public bool Equals(A data) { ... }
}
public class B
{
...
}
and a generic class for custom job
public class CommonFilter<T>
{
public T GetBy(T data) {
var item = list.FirstOrDefault(s=> s?.Equals(data) == true);
...
}
}
list if List<T> type.
CommonFilter<A> cmA = GetFilter();
var result = cmA.GetBy(data);
In debug mode, if I have object like CommonFilter<A>, I expected that in LINQ to use Equals method from A class, but it doesn't.
How to achieve this ?
As Jasper points out, you are missing a generic constraint:
public class CommonFilter<T> where T : IEquatable<T>
Whats not explained in the other answer is why its needed.
Bear in mind that the compiler needs to resolve the call s?.Equals(data) at compile time. In your code the compiler knows nothing about T and therefore resolves the call to the only possible candidate for any T: object.Equals which defaults to reference comparison.
If, on the other hand, you define the constraint then the compiler knows that any given T must implement the more specific IEquatable<T>.Equals and will resolve the call to that method.
If defining the constraint is a breaking change or you simply can't implement it because you also need to process data where reference equality is appropiate then you could branch inside GetBy on whether T implements IEquatable<T> or not, Type checking a generic type is normally a red flag but it could be justifiable in this particular scenario.
If possible, I prefer the first option because that way you specifically forbid using GetBy with types that do not implement IEquatable<T>.
I think you need:
public class CommonFilter<T> where T : IEquatable<T>

Inverting a generic constraint [duplicate]

This question already has answers here:
generic NOT constraint where T : !IEnumerable
(7 answers)
Closed 5 years ago.
I've been heavily learning generic constraints the last week. While learning them more in depth, I became curious if it's possible to invert them in some way. The people I work with aren't sure that such a thing exists and my google searching has also come up with nothing.
The closest answer I got was to use struct instead of class, but while I can see why the person thought this was a decent answer and would work for most of the uses, it still doesn't answer if there is a way of inverting the constraint.
Does anyone else know if it's possible to invert a constraint?
e.g.
class myClass<T> where T: !class
{
}
No, there is no such syntax in C#.
From MSDN:
The following table lists the six types of constraints:
where T: struct The type argument must be a value type.
Any value type except Nullable can be specified. See Using Nullable
Types for more information. where T : class The type argument must be
a reference type; this applies also to any class, interface, delegate,
or array type.
where T : new() The type argument must have a public
parameterless constructor. When used together with other constraints,
the new() constraint must be specified last.
where T : (base class name) The type argument must be or derive from the specified base
class.
where T : (interface name) The type argument must be or
implement the specified interface. Multiple interface constraints can
be specified. The constraining interface can also be generic.
where T : U The type argument supplied for T must be or derive from the
argument supplied for U.
So there is no option to say where T is any type other than U
Think about it this way - suppose you had
class myClass<T> where T: !string
{
}
You know T is not a string, but you have no other indication of what T might be. So how do you code against it? These would all be valid delcarations:
var x1 = new myClass<int>();
var x2 = new myClass<object>();
var x3 = new myClass<DateTime>();
var x4 = new myClass<DataTable>();
What code could you have that applies to all of these types, but would be invalid for string?

In C# how can I do a Dictionary of generics? [duplicate]

This question already has answers here:
Can I Create a Dictionary of Generic Types?
(11 answers)
Closed 9 years ago.
Lets say I have Generic class Foo<T>.
What i want to do is create a singleton for each of a variety of T, and then quickly retrieve them by T later on.
in pseudocode
STORE new Foo<int>
STORE new Foo<MyClass>
GET instance for MyClass -> returns the Foo<MyClass> created above.
In Java I'd make a dictionary that had Type for the key and Foo<*> for the value.
What is the equivalent magic in C#?
Dictionary<Type, object> Dict = new Dictionary<Type, object>();
void Store<T>(Foo<T> foo)
{
Dict.Add(typeof(T), foo);
}
Foo<T> Retrieve<T>()
{
return Dict[typeof(T)] as Foo<T>;
}
There are two ways a method may be given a type: as a Type parameter, or as a generic type parameter. In the former case, if the generic class Foo<T> inherits from a base class (e.g. FooBase) which is not generic in type T, one may use a Dictionary<Type,FooBase>. The FooBase class can include all the members (perhaps as abstract or virtual) of Foo<T> whose signature doesn't depend upon T, so code which is given a Type object for an arbitrary type but does not have a generic type parameter will be able to do with a FooBase anything that could be done without having a generic type parameter. Note that if one has a Type object and wants to use it as though it were a generic type, one will generally have to use Reflection and construct either a delegate or a generic class class instance with the type parameter filled in; once one has done that, one may use the second approach below.
If one has a generic type parameter available (e.g. one is writing a method T GetThing<T>(whatever), one may define a static generic class ThingHolder<T> with a static field T theThing. In that case, for any type TT, ThingHolder<TT>.theThing will be a field of type TT. One will be able to do with this field anything that can be done with a TT.

Get type name of T using reflection [duplicate]

This question already has answers here:
How to get the type of T from a member of a generic class or method
(17 answers)
Closed 9 years ago.
I have:
public class MyUserControl : WebUserControlBase <MyDocumentType>{...}
How do I get the TypeName of MyDocumentType if I'm in another class?
You can use something like this:
typeof(MyUserControl).BaseType.GetGenericArguments()[0]
There are plenty answers showing how to get the type of T if you know that the class derives directly from WebUserControlBase<T>. Here's how to do it if you want to be able to go up the hierarchy until you encounter the WebUserControlBase<T>:
var t = typeof(MyUserControl);
while (!t.IsGenericType
|| t.GetGenericTypeDefinition() != typeof(WebUserControlBase<>))
{
t = t.BaseType;
}
And then go on to get T by reflecting on the generic type arguments of t.
Since this is an example and not production code, I 'm not handling the case where t represents a type that does not derive from WebUserControlBase<T> at all.
You can use Type.GetGenericArguments method.
Returns an array of Type objects that represent the type arguments of
a generic type or the type parameters of a generic type definition.
Like
typeof(MyUserControl).BaseType.GetGenericArguments()[0]
Since return type of this method is System.Type[], the array elements are returned in the order in which they appear in the list of type arguments for the generic type.
If you are on .NET 4.5:
typeof(MyUserControl).BaseType.GenericTypeArguments.First();

Class syntax with <TypeParameter> C# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does “T” mean in C#?
What does <T> denote in C#
I have searched about the question, but because I do not have any idea about that syntax, I could not search well enough. Well, after the short explanation my question is :
While I was looking to a particle effect library I meet this :
[Serializable]
public class DPSF<Particle, Vertex> : IDPSFParticleSystem
where Particle : global::DPSF.DPSFParticle, new()
where Vertex : struct, global::DPSF.IDPSFParticleVertex
{
// constructors, methods, parameters here ...
}
What does this notation mean in blankets (<...>) and how it is used ?
They are generic types that you can pass into a class definition:
A simple example:
public class Test<T>
{
public T yourVariable;
}
Test<int> intClass = new Test();
Test<string> stringClass = new Test();
intClass.yourVariable // would be of type int
stringClass.yourVariable // would be of type string
Where T is the type you want (i.e. another class, a string, integer, anything generic)
where Particle : global::DPSF.DPSFParticle - means that the Particle object must inherit from DPSF.DPSFParticle
It means that DPSF class is a generic class. Particle and Vertex between <> are type parameters. It means that DPSF gets two types as parameters and serves as a generic class.
Take a look at here: MSDN: Generics
EDIT
Where keyword allows you to restrict type parameters. where:class means parameter must be a class in order this generic class to work.

Categories