Reputation: 2944
I'm trying to add a constraint to a generic method so it checks for ValueTypes, Strings or Nullable value types.
The problem is that:
So does anybody know if there's a way I can accept these and only these types in a generic constraint?
The problem is I'm trying to accept an Expression<Func<T, S>
parameter that will represent a property of these types for a given object.
The functionality would be something like the following (note the code doesn't make any sense and is just something quick to get an idea of what I'm looking for):
public class Person
{
public string Name {get; set;}
public DateTime? DOB {get; set;}
public int NumberOfChildren {get; set;}
public Car CurrentCar {get; set;}
}
---
internal void MyGenericMethod<T, S>(T myObject, Expression<Func<T, S> property){...}
Person myPerson = new Person();
MyGenericMethod(myPerson, p => p.Name); //S would be a string
MyGenericMethod(myPerson, p => p.DOB); //S would be a DateTime?
MyGenericMethod(myPerson, p => p.NumberOfChildren); //S would be a struct
The three calls above should all be accepted, but not the following:
MyGenericMethod(myPerson, p => p.CurrentCar); //S would be a class and shouldn't compile
Thanks in advance
UPDATE: Thanks Anton and Marc. MyGenericMethod has 4 different signatures accepting extra parameters, that's why I don't like the idea of creating 3 different (struct, nullable, string) for each of the existing 4... that would be a nightmare to maintain!
Upvotes: 6
Views: 4503
Reputation: 115711
The only thing I can come up with is a set of three functions (sans Expression<>
stuff):
MyGenericFunction<T>(T t)
where T : struct
MyGenericFunction<T>(T? t)
where T : struct
MyGenericFunction(string s)
UPDATE Given that there are various overloads of a method, I can suggest:
class Holder
{
private object value;
public Holder(object value)
{
this.value = value;
}
public static implicit operator Holder(DateTime dt)
{
return new Holder(dt);
}
public static implicit operator Holder(string s)
{
return new Holder(s);
}
// Implicit conversion operators from primitive types
}
Thus your method becomes
MyGenericMethod(Holder h);
Still very cumbersome, but nevertheless it might work out.
Upvotes: 7