This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can’t operator == be applied to generic types in C#?
I have a DatabaseLookup{} class where the parameter T will be used by the lookup methods in the class. Before lookup, I want to see if T was already looked up with something like
if (T == previousLookupObject) ...
This doesn't compile at all. What is preventing me from making a simple comparison like this?
T is the type parameter. If your previousLookupObject is an object of Type, you need to do typeof(T) == previousLookupObject.
If previousLookupObject is variable of type T, you need to have an actual object of T to compare it to.
If you want to find out if previousLookupObject is of type T, you need to use the is operator: if (previousLookupObject is T).
T is type, previousLookupObject is (I suppose) an object instance. So you are comparing apples to oranges. Try this:
if (previousLookupObject is T)
{
...
}
Refer to the following links:
Can't operator == be applied to generic types in C#?
c# compare two generic values
What type is previousLookupObject? Generic type parameters are types, and can't be used as normal object references.
Related
This question already has answers here:
Casting value to T in a generic method
(6 answers)
Closed 2 years ago.
I'm writing code that avoids the overhead of Convert.ChangeType(). But I'm getting hung up one one little detail, which is illustrated below.
public void GetValue(out T value)
{
if (typeof(T) == typeof(string))
value = (T)""; // <== Cannot convert 'string' to 'T'
// ...
}
I have a value that I know is of type T, but how can I assign that value to an instance of type T with minimal overhead? I'm really hoping for something fast and simple. Otherwise, I'll scrap my code and use Convert.ChangeType() in a try...catch block.
You need to cast it to object first:
value = (T)(object)"";
Even though you've done a check for type compatibility the compiler doesn't look at this. As far as it's concerned you've got a T and a string which there isn't a direct cast. You have to bounce the string down to an object first (for which there is a direct cast) and then cast to T which as far as the compiler is concerned may fail, but won't because you've already checked the type!
This question already has answers here:
Passing dynamic object to C# method changes return type
(2 answers)
Closed 4 years ago.
I have the following generic method signature
public static T? TryConvertToEnum<T>(object obj, T? defaultValue = null) where T : struct, IConvertible
which is working fine! The problem I have is there seems to be a unexpected behaviour from VS in this call:
dynamic dynamicValue = "1";
var value= ConversionHelper.TryConvertToEnum<MyEnum>(dynamicValue);
the problem is that the Type of "value" is "dynamic" and I don't know why I'd expect it to be "MyEnum?"
Did anyone expected this behavior or know why this is happening?
Almost everything you do with a value of type dynamic results in a value of dynamic. Sure, you know the return type of the TryConvertToEnum method you intend to call - but you're passing in a dynamic argument, which means it's not bound until execution time. At execution time, there could be a whole other method with a string parameter and a different return type.
There are a very few cases of expressions which include dynamic values but still don't have a result type of dynamic. Off the top of my head, they are:
Constructor calls (always the type being constructed)
The is operator (always bool)
The as operator (always the type named as the second operand)
In your case, just use object instead of dynamic and the call will be statically bound instead, and value will be of type MyEnum?.
This question already has answers here:
Solution for overloaded operator constraint in .NET generics
(4 answers)
What are generics in C#? [closed]
(3 answers)
Closed 6 years ago.
Generics are used to decouple logic from data type.
public class Calc<T>
{
public T Add(T a, T b)
{
return (a+b);
}
}
But this is throwing the below compile time error
Operator + cannot be applied on type T.
I am not understanding why so. because if it allows from main.cs
main()
{
Calc<int> obj = new Calc<int>();
int c = obj.Add(10,20);
}
Can somebody please explain why I am getting Build errors??
C# generics don't support arbitrary operators. The exact (possibly virtual) method must be known at compile-time of the generic type. Since the generic type argument in your example isn't constrained at all, you can only use the members of the object type, which doesn't include a + operator.
There's no way to use C# generics to do what you're trying to do, sorry. The best you can do is a bunch of type-checks for a few known types (and the appropriate casts, which are tricky with value types), or using reflection (dynamic in particular will work great).
Unrestricted generics like your Calc<T> must be able to compile with any type applied, not all types support the + operand so your code does not compile. This is regardless of what specific types you create your calling code with.
You can restrict the type of T and thus gain access to more methods by doing Calc<T> where T:object or Calc<T> where T: IComparable which would allow you to:
public T CompareTo(T a, T b)
{
return (a.CompareTo(b));
}
Since all T must now implement IComparable. Unfortunately Int32 does not implement any interface which defines the + operator or any addition method. So there is no way to implement that statement you are trying.
C# generics are different from C++ templates. The C# code cannot be compiled if generic type doesn't have definition for used method (operator+ in your case), while C++ compiler applies this method to the actual template argument type.
Addition is not allowed because there is no guarantee that passed types have operator + overload.
There is a way to accomplish that but it will work as long as you pass types that have operator +. Otherwise, RuntimeBinderException will be thrown. Also, there is some impact on performance, but unless code is performance critical, shouldn't be a problem.
public T Add<T>(T a, T b)
{
dynamic da = a, db = b;
return da + db;
}
This question already has answers here:
How can I call default(T) with a type? [duplicate]
(3 answers)
Closed 10 years ago.
I am using reflection to get all the properties of an object. I then need to see if any of those property’s values are the default of whatever type they happen to be. Below is my current code. It is complaining that the namespace or type could not be found. This leads me to believe that it has something to do with how c# does implicit type coercion. Since I am grabbing the type at run time it does not know how to compare it or something not really clear on that.
I was hoping to avoid a switch case comparing on the name of the type that comes in but right now that is looking like my only option unless the brilliant people on StackOverflow can lead me in the right direction.
private bool testPropertyAttribute(PropertyInfo prop)
{
dynamic value = prop.GetValue(DataObject, null);
Type type = prop.PropertyType;
/* Test to see if the value is the defult of its type */
return (value == default(prop.PropertyType)
}
== for object will always mean: reference equality. For a reference, the default is always null, so if !prop.PropertyType.IsValueType, then you only need a null check. For value-types, you will be boxing. So reference equality will always report false, unless they are both Nullable<T> for some T, and both are empty. However, to get a "default" value-type (prop.PropertyType.IsValueType), you can use Activator.CreateInstance(prop.PropertyType). Just keep in mind that == is not going to do what you want here. Equals(x,y) might work better.
You can do this you just cannot rely on the == operator to do the work. You'll want to use .Equals or object.ReferenceEquals to do the comparison.
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?