C# generic constraints : Interface - c#

I got a question for some code:
interface IDistance<T>
{
double distance();
double distance(T obj);
}
class Point<T> where T : IDistance<T> //why do i need this?
{
T obj;
public double dist(T val) { return obj.distance(val);
public Point(T obj) { this.obj = obj; }
}
class P2D : IDistance<P2D>
{
public double[] x = new double[2];
public P2D(double x, double y)
{
this.x[0] = x; this.x[1] = y;
}
public double distance()
{
double d = 0.0;
for (int i = 0; i < 2; i++) d = d + x[i] * x[i];
return Math.Sqrt(d);
}
public double distance(P2D val)
{
double d = 0.0;
for (int i = 0; i < 2; i++) d = d + Math.Pow(x[i]-val.x[i],2);
return Math.Sqrt(d);
}
}
class Tester
{
static void Main(string[] args)
{
P2D P1 = new P2D(3.0, 4.0);
Point<P2D> C1 = new Point<P2D>(P1);
Console.WriteLine(C1.dist());
}
}
The code in detail is rather unimportant.
Why do I need the constrain where T : IDistance<T> in the generic class Point<T>?
When I only specify classes that already implemented the interface IDistance<T> like
Class P2D, shouldn't be the interface already implemented implicit in the class Point?
I get the fact that it can cause problems, when a class as type <T> in class Point is defined that has not implemented the interface. But in this case, why is it not possible?

Look at this code within Point<T>:
T obj;
public double dist(T val) { return obj.distance(val);
When the compiler tries to understand what this expression means:
obj.distance(val)
it has to resolve the distance member. If T is unconstrained, it can't do that. When T is constrained to implement IDistance<T>, it can - it resolves it to the member of the interface.
In particular, without the constraint, I could use the type in very odd ways:
Point<string> weird = new Point<string>("foo");
double result = weird.dist("bar");
What would you expect that to do?
(As a side note, it would be worth following normal .NET naming conventions, even for examples. Methods should be PascalCased, and I'd never call a class P2D...)

When I only specify classes that already implemented the interface IDistance like Class P2D, shouldnt be the interface already implemented implicit in the Class Point? I get the fact that it can cause problems, when a class as type in Class Point is defined that has not implemented the interface. But in this case, why is it not possible?
Because C# is a language that has compile-time type safety. Without that constraint, you may only ever instantiate Point<T> with values of T at run-time which implement IDistance<T>, but there's no way for the compiler to know at compile-time that you will be so well-behaved.

why do i need this?
You need the constraint because you are restricting the generic type to be an implementation of the interface, IDistance<T>. If Point class you use some methods from this type like obj.distance(val);.
You also could use a abstract class to restrict derivations. Take a look at documentation in MSDN.
http://msdn.microsoft.com/en-us/library/bb384067.aspx

class Point<T> where T : IDistance<T> //why do i need this?
You need this becuase the class you declare, should take as type a type that implements the interface called IDistance<T>

Related

Unable to cast constrained generic interface reference to covariant interface reference

I'm trying to understand how covariance works with generic type constraints and it seems like the constraints are ignored for no obvious reason.
Consider the following code:
public interface IContainer<out T> { }
public interface IContents { }
public class Food : IContents { }
public class Foo
{
public void Bar<T>() where T : IContents
{
IContainer<IContents> x = null;
IContainer<T> y = null;
IContainer<Food> z = null;
x = y; // Cannot convert source type 'IContainer<T>' to target type 'IContainer<IContents>'
x = z; // Valid
}
}
Why does compiler produce 'Cannot convert' error on x = y and produce no error on x = z?
C# does not support variance for value types - see the variant generic interfaces doc:
ref, in, and out parameters in C# cannot be variant. Value types also do not support variance.
i.e. the following will not work:
public struct MyStruct : IContents
{
}
var structContainer = (IContainer<MyStruct>)null;
IContainer<IContents> x = structContainer;
Since T is not constrained neither to class not to struct it can be either reference type or value type, so in general case IContainer<T> is not assignable to IContainer<IContents>.
Add class constraint to the Bar method:
public class Foo
{
public void Bar<T>() where T : class, IContents
{
IContainer<IContents> x = null;
IContainer<T> y = null;
IContainer<Food> z = null;
x = y; // Now Valid
x = z; // Valid
}
}

how to use interface and purpose of casting?

i have used interface in both cases. is it my first case use interface ??
here is the my interface and class
interface IAddition {
int Add();
}
interface IMultiplication {
int Multiplication();
}
it is my class
public class Calculation : IAddition, IMultiplication {
int x, y;
public Calculation(int x, int y) {
this.x = x;
this.y = y;
}
public int Add() {
return (x + y);
}
public int Multiplication() {
return (x * y);
}
}
1st case is this
class Program {
static void Main(string[] args) {
Calculation cal = new Calculation(20, 30);
Console.WriteLine("Sum is= " + cal.Add());
Console.WriteLine("Multiplication is= " + cal.Multiplication());
Console.ReadKey();
}
}
And 2nd case is this
class Program {
static void Main(string[] args) {
Calculation cal = new Calculation(20, 30);
IAddition add = (IAddition)cal;
IMultiplication mul = (IMultiplication)cal;
Console.WriteLine("Sum is= " + add.Add());
Console.WriteLine("Multiplication is= " + mul.Multiplication());
Console.ReadKey();
}
}
What is the purpose of these 2 lines ??? here what is the purpose of casting ?? Although 1st case have same output
IAddition add = (IAddition)cal;
IMultiplication mul = (IMultiplication)cal;
Only the second case programs to IAddition and IMultiplication interfaces. The first case would work even if the Calculation class did not implement IAddition and IMultiplication.
what is the purpose of casting?
Note that since you declare variables with an explicit interface type, you can safely drop the casts in the declarations of mul and add:
IAddition add = cal;
IMultiplication mul = cal;
You could also rewrite your declarations with implicit type declaration:
var add = (IAddition)cal;
var mul = (IMultiplication)cal;
What is the purpose of these 2 lines?
These lines declare two variables using the interface type implemented by Calculation. They make no practical difference in this example, but generally you could use add and mul to be specific about the level of abstraction to which you program. For example, IAddition add tells the readers of your program that you do not need to use any aspects of cal except these related to addition.
The other answers cover the given example code, but it's worthwhile to add that the rules are different for explicit interface implementation.
For example, if the example class was implemented as follows:
public class Calculation : IAddition, IMultiplication {
int x, y;
public Calculation(int x, int y) {
this.x = x;
this.y = y;
}
public int IAddition.Add() {
return (x + y);
}
public int IMultiplication.Multiplication() {
return (x * y);
}
}
then the cast is required. For example:
Calculation cal = new Calculation(10, 10);
cal.Multiplication(); // this will cause a compiler error
((IMultiplication)cal).Multiplication(); // This is the required way to do it
For more information see this article on MSDN
In this case, the purpose is just to show you how you can cast types. It doesn't make a difference in how the code works, but you can see that if you were to try add.Multiplication(), the compiler would tell you that's not allowed.
In a simple example like this, there's no reason to cast and declare variables like this. However, in larger applications, the Interface Segregation Principle helps us to avoid tight coupling of different pieces of code. For example, you could write a method like this:
int SumAll(IAddition adder, params int[] values)
{
int sum = 0;
foreach(int n in values)
{
sum = adder.Add(sum, values[i]);
}
return sum;
}
The above method would work just fine if you pass it a Calculator, but it doesn't have to use a Calculator. Since you know you don't need to multiply anything in this method, this limits your dependencies to the things that you actually need. You might in the future find it useful to implement an Add method with a ceiling, for example, that never allows numbers to go above a certain number, no matter how many things get added. Passing that IAddition object into SumAll would have a different effect, and you wouldn't have to create a different SumAll method to accommodate this need.
Console.WriteLine(SumAll(new Calculator(), 1, 2)); // 3
Console.WriteLine(SumAll(new Calculator(), 1, 2, 3)); // 6
Console.WriteLine(SumAll(new AdderWithMax(4), 1, 2)); // 3
Console.WriteLine(SumAll(new AdderWithMax(4), 1, 2, 3)); // 4
In general, people find that by separating interfaces intelligently, they're able to write code that's easier to test and less likely to require as much work when changes are made in the future--in other words, more maintainable code.
Oh, and by the way, the explicit cast isn't actually necessary, so this would also have the same effect:
IAddition add = cal;
or:
var add = (IAddition)cal;
how to use interface
There are many ways to use an inteface, from implementation to type-checking.
// Definition of interface or sometimes referred to as "Contract"
// Implementing classes must define these methods and properties
public interface IMyInterface
{
void MyMethod();
int MyProperty { get; }
}
// Implementation or sometimes referred to as "Concrete type"
public class MyClass : IMyInterface
{
public void MyMethod();
public int MyProperty { get; set; }
}
// Compile time type checking:
public void MyMethod<T>(T value)
where T : IMyInterface
{ }
// Runtime checking
public void MyMethod(object someobject)
{
var myinterface = someobject as IMyInterface;
if (myinterface != null)
{
//someobject implements IMyInterface so I can do things with it
someobject.MyMethod();
}
}
and purpose of casting?
The purpose of casting is has many uses. I'll mostly be demonstrating use the as keyword because it provides type-safety for the run-time.
You can use it to validate a type implements an interface at run-time:
public MyMethod(object obj)
{
var calc = obj as ICalc;
if (calc != null)
{
calc.Calculate();
}
}
This can be improved:
public void MyMethod(ICalc calc)
{
calc.Calculate();
}
Using generics and compile time type safety (I think it's important to show).
public void MyMethod<TObject>(TObject calc)
where TObject : ICalc
{
calc.Calculate();
}
is it my first case use interface ??
I'm not sure what this means, I think what you are trying to say is
Am I required to use the interface by casting it?
No you are not. Lets take a look at these two classes:
public class Calculation1 : IAddition, IMultiplication {
public int Add() { //... ignoring implemenetation
}
public int Multiplication() { //... ignoring implemenetation
}
}
public class Calculation2 {
public int Add() {//... ignoring implemenetation
}
public int Multiplication() {//... ignoring implemenetation
}
}
Both of the classes implement the same methods so these are valid:
var one = new Calculation1();
one.Add();
var two = new Calculation1();
two.Add();
However because the first one implements an interface and the second one does not, you can pass the first object to methods that do not need to know the concrete type.
public void MethodNeedsToAdd(IAddition addCalculator)
{
if (addCalculator != null)
{
addCalculator.Add();
}
}
MethodNeedsToAdd(one); // Valid
MethodNeedsToAdd(two); // Invalid
Even though you and I can clearly see they both can "Add" the second class two does not implement the interface.
It's all about concealing complexity. When you do this cast ...
IAddition add = (IAddition)cal;
You can then handle this add item as if all it can do is implement your IAddition interface. That might prove convenient if you were implementing a complex system.
For example, you might define an IGetNextItem interface. Then, you might choose to implement that interface in a class which fetched an item from a DBMS, and another which generated a random fake item. You would be able to cast either object, and then pass it to some software which consumed those items, without needing to tell the consuming software exactly how the fetching of items actually works.
You don't need the cast. You can say...
IAddition add = cal;
However, the point of that is you are creating an object of any type that implements the IAddition interface.

Implicit and explicit method hiding

I have the following two use cases:
class BaseCalculator
{
public int Sum(int x, int y)
{
return x + y;
}
}
class Calculator : BaseCalculator
{
public new int Sum ( int x , int y )
{
return x + y;
}
}
This did explicitly hide the Sum method using the new keyword.
class BaseCalculator
{
public int Sum(int x, int y)
{
return x + y;
}
}
class Calculator : BaseCalculator
{
public int Sum ( int x , int y )
{
return x + y;
}
}
I didn't understand the difference between the two. Does the second code implicitly hide the Sum method?
From MSDN documentation:
In C#, derived classes can contain methods with the same name as base class methods. If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.
And why the two code pieces are the same is explained below:
Using the new keyword tells the compiler that your definition hides the definition that is contained in the base class. This is the default behavior.
The only difference is that by using new keyword, you avoid the compiler warning.
More explanation can also be found on MSDN in Knowing When to Use Override and New Keywords (C# Programming Guide).
Yes it does. There is no semantic difference. The new keyword merely emphasizes the hiding. It is similar to the behavior of the private modifier. Members are private by default, but you can write private anyway.

Why does C# tease with structural typing when it absolutely knows it doesn't have it?

I was surprised to see today that this was possible, but I worry this must be discussed before.
public interface ICanAdd
{
int Add(int x, int y);
}
// Note that MyAdder does NOT implement ICanAdd,
// but it does define an Add method like the one in ICanAdd:
public class MyAdder
{
public int Add(int x, int y)
{
return x + y;
}
}
public class Program
{
void Main()
{
var myAdder = new MyAdder();
var iCanAdd = (ICanAdd)myAdder; //compiles, but for what sake?
int sum = iCanAdd.Add(2, 2); //na, not game for it, cast had already failed
}
}
The compiler will (rightly?) tell me that an explicit cast exists in the above situation. I was all thrilled to sense structural typing in there, but no run time it fails. So when is C# being ever helpful here? Any scenarios such casting would work? Whatever it is, I'm sure compiler beforehand knows myAdder is not ICanAdd, well technically.
C# allows an explicit conversion from a class to an interface (even if the class doesn't implement that interface), because for all the compiler knows, a reference to a certain type might actually (the uncertainty is why it's an explicit rather than implicit conversion) be an instance of a derived type that does implement the interface. Extending your example, suppose you have:
public class DerivedAdder : MyAdder, ICanAdd
{
int ICanAdd.Add(int x, int y)
{
return base.Add(x, y);
}
}
...
MyAdder myAdder = new DerivedAdder();
var iCanAdd = (ICanAdd)myAdder; // Valid in this case
int sum = iCanAdd.Add(2, 2); // sum = 4
If you check section 6.2.4 of the C# Specification, you'll see that if you mark your MyAdder class as sealed, the compiler will actually complain, because then it will know for sure that no conversion is possible, since no derived type could exist. But as long as it can't eliminate every last shred of doubt, it'll allow an explicit conversion.
Casting class to interface is allowed by C# language specification. But for example if ICanAdd was a class - compilation would fail

Casting one generic to another, without class constraints

I have the following code:
public interface IDrilldown
{
void AddCriteria<T>(T Criterion);
}
public class MyClass<W> : IDrilldown // where W : class
{
void IDrilldown.AddCriteria<T>(T Criterion)
{
W value = Criterion as W;
...
}
}
Unfortunately, the cast I have above will not work unless W has the constaint in the code. I would like to have this using value types. Is it at all possible?
I cannot make W and T the same type. My interface does not have a type associated with it globally, only the internal data types.
This is so that I can have a List all having different T's
I was able to find a way to do it, it's a little hacky but allows it to work:
class MyClass<W> : IDrilldown {
void IDrilldown.AddCriteria<T>(T Criterion) {
if (Criterion is W) {
W value = (W)Convert.ChangeType(Criterion, typeof(W));
// value is W, have fun
// or - as Snowbear pointed out in the comments
W value = (W)(object)Criterion;
// works just as well....
} else {
// value is NOT W and could not be converted.
}
}
}
The only drawback with this is, Convert.ChangeType will use converters to change between internal objects, so string value = (string)Convert.ChangeType(1, typeof(string)) will work and return "1" instead of throwing an exception.
To clarify on how this works, the documentation states:
For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. The method requires that conversion of value to conversionType be supported.
so for this method to work with custom types you will need to implement the IConvertible interface to convert from one custom type to any other type. In the code sample above, if both T and W are the same type, the Convert.ChangeType will succeed, even if the custom object does not implement IConvertiable.
Would the dynamic keyword help you out?
Something like this:
public interface IDrilldown
{
void AddCriteria<T>(T Criterion);
}
public class MyClass : IDrilldown
{
void IDrilldown.AddCriteria<T>(T criterion)
{
dynamic value = criterion;
// can use typeof() to figure out type if needed...
...
}
}

Categories