Generic constraints, where T : struct and where T : class
Constraints are not part of the signature, but parameters are. And constraints in parameters are enforced during overload resolution.
So let's put the constraint in a parameter. It's ugly, but it works.
class RequireStruct<T> where T : struct { }
class RequireClass<T> where T : class { }
static void Foo<T>(T a, RequireStruct<T> ignore = null) where T : struct { } // 1
static void Foo<T>(T? a) where T : struct { } // 2
static void Foo<T>(T a, RequireClass<T> ignore = null) where T : class { } // 3
(better six years late than never?)
Struct and string generic constraint on class level
No, it's not possible. The best approach is to use an abstract generic base class and specialize for string
and struct
.
public abstract class AutoEncryptorBase<T>
{
protected T _value;
}
public class AutoEncryptor<T> : AutoEncryptorBase<T?> where T : struct
{
}
public class TextAutoEncryptor : AutoEncryptorBase<string>
{
}
Generic constraints to a specific class, why?
Perhaps this simple example might help.
If I have these classes:
public class ListOfCars<T> : List<T> where T : Car { }
public abstract class Car { }
public class Porsche : Car { }
public class Bmw : Car { }
...and then if I write this code:
var porsches = new ListOfCars<Porsche>();
// OK
porsches.Add(new Porsche());
//Error - Can't add BMW's to Porsche List
porsches.Add(new Bmw());
You can see that I can't add a BMW to a Porsche list, but if I just programmed off of the base class it would be allowed.
C# generic constraint: Array of Structs
You don't need to.
Just constrain it to : struct
, then write T[]
instead of T
when using the type parameter.
public class DeepCopyArrayOfValueTypes<T> : IDeepCopyable<T[]>
where T : struct
{
public T[] DeepCopy(T[] t) {...}
}
Combining struct and new() generic type constraints
For struct new doesn't make sense. For classes it does.
In your case it is a redundant.
public T FactoryCreateInstance<T>() where T : new()
{
return new T();
}
It make sense to specify new constraint in a case like above but not when it is already constrained to be struct.
Parameter less constructor for value types is a C# restriction and not a CLI restriction. Maybe this is why is it specified redundantly to leave some wiggle room for future.
generic function that can return T? or T depending on whether T is struct or class
No. Neither the return type nor generic constraints are part of the method signature for binding purposes, so there is no way to disambiguate those methods at compile-time.
You could use dummy input parameters like the marked duplicate answer does to disambiguate them:
public T Get<T>(RequireClass<T> ignore = null) where T : class
public T? Get<T>(RequireStruct<T> ignore = null) where T : struct
public class RequireStruct<T> where T : struct { }
public class RequireClass<T> where T : class { }
What does where T : class, new() mean?
That is a constraint on the generic parameter T
. It must be a class
(reference type) and must have a public parameter-less default constructor.
That means T
can't be an int
, float
, double
, DateTime
or any other struct
(value type).
It could be a string
, or any other custom reference type, as long as it has a default or parameter-less constructor.
C# Generics: Constraining T where T : Object doesn't compile; Error: Constraint cannot be special class 'object'
There is no difference between the two constraints, except for that one is disallowed for being useless to explicitly state.
The C# 4.0 language specification (10.1.5 Type parameter constraints) says two things about this:
The type must not be object. Because all types derive from object,
such a constraint would have no effect if it were permitted....
If T has no primary constraints or type parameter constraints, its
effective base class is object.
In your comment, you said that you were trying to make T
be of type Void
. Void
is a special type that indicates that there is no return type and cannot be used in place of T
, which requires an appropriate concrete type. You will have to create a void version of your method and a T
version if you want both.
Related Topics
What Strategies and Tools Are Useful for Finding Memory Leaks in .Net
Itextsharp Insert Text to an Existing PDF
Multi-Threaded Splash Screen in C#
Passing Data Between Different Controller Action Methods
Linq to Entities Does Not Recognize the Method Last. Really
Concat All Strings Inside a List<String> Using Linq
Converting String to Double in C#
How to Write an Async Method with Out Parameter
Merging Multiple PDFs Using Itextsharp in C#.Net
Getfiles with Multiple Extensions
.Net Hashtable VS Dictionary - Can the Dictionary Be as Fast
Reference Assignment Is Atomic So Why Is Interlocked.Exchange(Ref Object, Object) Needed