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;
}
Related
I'm currently implementing a simple version of algorithmic differentiation with operator overloading in C#. I'm trying to figure out how to design generic math functions that works for with ordinary doubles and my own class "ADouble" that works like a double, but overloads arithmetic operators like +,*,- and so forth.
For instance, i would like to create a function like
Public T MathFunction<T>(T x) where T : "is either double or Adouble"
{
if (x > 0)
return new T(1.0)
else
// something
}
that works for both doubles and ADoubles. In this case it's necessary for me to "new up" a specific value (here 1.0). In other cases i might have to do something like
Public T MathFunction<T>(T x) where T : "is either double or Adouble"
{
T temporaryVar = 2*x;
// .. More calculations
return "some T";
}
I have implemented the necessary interfaces to do a comparison like the above, but i cannot get the rest to work.
I can instantiate my ADouble class with a double by, say
Adouble myADouble = new ADouble(12.3);
but doubles does not have a constructor that works that way, obviously. I've tried different things. First of all i thought of something like
if (typeof(T) == typeof(ADouble)
return new ADouble(1.0)
but this does not work, since the function cannot cast ADouble to a T explicitly (which i understand).
Does anyone have a suggestion on how i could go about implementing generic calculation functions that works with my ADouble class and doubles? Or is the only option to make multiple methods with different signatures? Different suggestions for designs is also greatly appreciated.
Or is the only option to make multiple methods with different signatures?
Called "method overloading".
Yes. This is the correct way to express your "type A or type B" constraint, especially since even if you could successfully express that as a generic constraint, you are still left with the challenge of calling the appropriate constructor.
There is no mechanism in C# generics by which the statement return new T(1.0); could be made to compile successfully. Doing so would require some syntax that additionally constrains the types to those with a constructor that has a single parameter of type double, and there is no such feature in C#.
this does not work, since the function cannot cast ADouble to a T explicitly
Actually, it's that it can't cast implicitly. But, close enough. :)
That would be the next hurdle you'd have to clear. Ironically, this is the simplest. The issue there is that, as you wrote the expression, the compiler knows enough about what's going on to know it can't guarantee the cast will succeed. But if you cast the value to object first, you can then cast it to T without the compiler complaining.
Not that I'm suggesting doing that, mind you. The real issue here is that you are trying to use generic syntax for something that really isn't generic. Generic code is for where you can use any type, or at least a broadly constrained type. If you have specific types in mind, and especially if the implementation is different for each specific type, then you should not be using generics.
In that situation, method overloading is much more appropriate.
Aside: assuming your ADouble type is literally equivalent to double, and you can implement a conversion without any loss of data, you should consider writing an implicit conversion, to help make the types interchangeable. That would look something like this:
public static implicit operator ADouble(double value)
{
return new ADouble(value);
}
Then you can initialize ADouble values with simple assignments, like:
ADouble adouble = 1.0;
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
In answering this question: Is there a way to return Anonymous Type from method?, Andrew Hare states that
Returning it as a System.Object is the only way to return an anonymous type from a method. Unfortunately there is no other way to do this since anonymous types were designed specifically to prevent their use in this way.
Can anyone elaborate on that?
I mean that the C# team could have implemented the equivalent of the var keyword for method return types, and type the method based on the type of the return statement.
as in:
public var myMethod()
{
var x = new {A="blah"};
return x;
}
And then let the type inference do the job for the consuming functions.
That would have been helpful for Linq statements that want to call methods instead of chaining lambdas (which can return anonymous types, btw).
But apparently, this was done by design. I can't see the trade-off though, does anyone know?
This is only a guess, and you said you could find no trade-offs. One major one is it can't be used for interfaces.
Show me how you would put myMethod() in a interface then consume it from another assembly that only has a copy of the interface to reference and can't reference the implementation.
There is no way to represent the annonamous type in the interface and making it so "you can use interfaces on all public non-static methods, except for the ones with a implicit return type" would be too much of a departure of the standard pattern.
If you are using C# 7 you could use the new Tuples feature to achieve a similar goal.
public (string A, int Answer) myMethod()
{
return (A: "Blah", Answer: 42);
}
This can be used with a interface
public interface IExample
{
(string A, int Answer) myMethod();
}
Think that sharing an anonymous type outside a given method body would mean that the whole type may be more useful than you expect. For example, you might want to inherit it, implement an interface on it.
Also, what would happen when you would want to upcast an anonymously-typed object to object and later to the anonymous type again...? You would have lost the type after all... There're too many issues to solve and it's a sign to think that anonymous types are just fine right now.
Basically this is the reason to avoid exposing anonymous types outsides the boundaries of their limited scope.
Actually anonymous types are named types once they get built into intermediate language (IL). That is, it's a syntactic sugar provided by the C# grammar/compiler to lie you and make you believe that you're creating a typed object as you instantiate it.
Another point of view to understand why anonymous type shouldn't be exposed that way is that it would be painful to maintain and evolve a strongly-typed code base on which you need to look into method bodies to check how's the whole type...
Anyway, you might be interested in C#7's tuples:
public (string x, int y) DoStuff()
{
return ("hello world", 283);
}
Aren't tuples what you propose for anonymous types? ;)
I think you are confusing runtime behavior with compile time behavior. Imagine if your code looked like this:
public var myMethod(int i)
{
if (i = 0) {
var x = new {A="blah"};
return x;
}
else {
var a = new {K=14};
return a;
}
}
How would type inference work in that case? It would be confused because the returned type could be anything. You could return a Tuple<> or a dynamic type both have there pros and cons.
This question already has answers here:
Implicit Conversion over a Collection
(4 answers)
Closed 7 years ago.
I created simple type that contains only one dependency property "Text" returns string. For easy conversion from string to my type I wrote this code:
public static implicit operator string(StringDP sdp)
{
return sdp.Text;
}
public static implicit operator StringDP(string str)
{
return new StringDP(str);
}
I want to have similar conversion from List<string> to List<myType>. Am I able to do this? Or I have to use something like this:
public List<string> Convert(List<myType> lst);
public List<myType> Convert(List<string> lst);
Thank you!
No, this is not possible. From the documentation:
Either the type of the argument to be converted, or the type of the result of the conversion, but not both, must be the containing type.
Both of the types involved in your hypothetical implicit conversion are concrete versions of the generic List<T> class. Since you can't add operators to the List<T> class yourself, and since that's where the implicit operators to achieve your goal would have to be, it can't be done.
Without more context, I admit that I can't really comment knowledgeably on the implicit conversion to and from string that you've defined. But in general, you should be very careful with implicit conversions. Assuming the implicit conversion of your type fits within the "safe" guidelines, then a conversion of a whole list of the type would be "fine".
This conversion can be done with custom methods such as your examples. Or you can use LINQ or the List<T>.ConvertAll() method. E.g.:
List<string> listOfString = listOfMyType.Select(item => (string)item).ToList();
List<myType> listOfMyType = listOfString.ConvertAll(item => (myType)item);
// etc.
However, even there I would suggest that you should be careful about how you are using something like that. It's one thing to convert a single instance of a value, but converting a whole collection involves quite a lot more overhead and most likely is not the correct way to solve the problem.
Not know what the actual problem is, I can't offer an alternative. Just to suggest you be very wary of the design path you appear to be headed down.
I was wondering if C# supported implicit type discovery for class generics.
For example, such functionaly exists on method generics.
I can have the following method:
public void Foo<T>(T obj);
And call it like this:
int n = 0;
instance.Foo(n);
As you can see, I'm not specifying the <int> generic constraint. It's being implicitly discovered, because I passed an int value.
I want to accomplish something similiar on a class definition level:
internal interface IPersistenceStrategy<E, T> : IDisposable
where E : UniqueEntity<T>
I want it to be defined as IPersistenceStrategy<MyEntity>, where MyEntity is an UniqueEntity<int>.
As you can see, the T type param, is being implicitly discovered from MyEntity.
However, this does not work. I have to supply the T param explicitly:
IPersistenceStrategy<MyEntity, int> myStrategy;
Why is this functionality not working? Is C# compiler not smart enough to discover my type param automatically?
Is there some way to accomplish what I am looking for?
There is no type inference in generic type declarations on initialization. You can only omit the generic argument when calling a generic method but it is not the case with initializing a generic type for example:
var list = new List { 2, 3, 4 };
Here you may expect compiler to see that you wanna create a list of int so there is no need to specify type argument.But it is not the case.
In your specific example let's assume compiler has inferred this :
IPersistenceStrategy<MyEntity> myStrategy;
as IPersistenceStrategy<MyEntity,int> then what should happen if there is another declaration in the same assembly such as:
interface IPersistenceStrategy<T> { }
Ofcourse this would cause an ambiguity. So that might be the one of the reasons why it is not allowed.
C# has type inference for methods, but not for constructors. This feature was proposed to be in C# 6 version, but seems was removed from release according to Mads Torgersen (http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx).
Also have a look to Languages features in C# 6 and VB 14, i.e. there is no mention about it
This question already has answers here:
Method overload resolution with regards to generics and IEnumerable
(2 answers)
Closed 8 years ago.
So, I'm having an issue with similar code to below:
public static String MyFunc<T>(this IEnumerable<T> list) where T : struct
{
... some code ...
return myString;
}
public static String MyFunc<T>(this T o) where T : struct
{
... some code ...
return myString;
}
The problem is that when trying to do call MyFunc on a List it uses the second function instead of the one that accepts an IEnumerable. I know this has to do with variance, but I'm uncertain as to how to force it to use the first function rather than the second. The code I would use to call the first one would be:
List<int> x = new List<int>();
String s = x.MyFunc();
The above code immediately goes to the second function and I need it to use the first. How can I force the desired behavior? Incidentally, I'm using .NET 4.0
The reason that it's currently picking the second method is that a conversion from a type to itself (second method, T=List<int>, conversion from List<int> to List<int>) will always be "better" than a conversion to the type it implements (first method, T=int, conversion from List<int> to IEnumerable<int>). This has nothing to do with variance, by the way - it's just the method overloading algorithm and type inference.
Note that with your current code, although the second overload is picked, it will then be found to be invalid because T violates the T : struct constraint. The constraint is only checked after the overload is chosen. See Eric Lippert's blog post on this for more details.
I suggest you just give the two methods different names.
EDIT: As noted by Anthony in comments, this can work if you call it as:
x.AsEnumerable().MyFunc();
Or just change the declaration to:
IEnumerable<int> x = new List<int>();
x.MyFunc();
It's not entirely clear to me exactly why it's better here - in this case after type argument substitution, you've basically got IEnumerable<T> as the parameter type in both cases. However, I would still strongly recommend using different names here. The fact that it's got me puzzling over the spec to work out which overload is being called should be enough indication that the behaviour won't be immediately clear to everyone reading the code.
EDIT: I think the reason is here (from the C# 5 spec, section 7.5.3.2):
A type parameter is less specific than a non-type parameter
So just T is less specific than IEnumerable<T>, even though the latter involves a type parameter. It's still not clear to me whether this is the language designers' intended behaviour... I can see why a type which involves type parameters should be seen as less specific than a type which doesn't involve type parameters, but not quite this wording...