Assuming
class A { }
class B : A { }
covariance is not supported for generic class.
Meaning - we cant do something like this :
MyConverter<B> x1= new MyConverter<B>();
MyConverter<A> x2= x1;
Thats fine and understood.
From my reading - i understand that Covariance will be available:
"If you use a backing Generic Interface Being implemented on a Generic Class - so that access to the T type object instance will be available through those interfaces ".
I have just one problem.
Ive seen many examples of the "converter" class as a form of Stack
.
But never understood " what if I want to use only 1 instance of B from a reference of A ? "
so Ive tried some code :
Create
B
object + values ---> use Generic Converter forB
---> use the covariance flow to get itsA
reference ---> now you can use it either as A or as B.
My question :
Is That the correct way of doing this ( for using covariance for 1 object only ) ?
p.s. The code is working and compiled ok. http://i.stack.imgur.com/PJ6QO.png
Ive been asking /reading a lot about this topic lately - I dive into things in order to understand them the best I can.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.
Your code compiles and works, so is it "correct"? I guess it is!
However it is not very interesting having a stack that only contains a single element; that's not really a stack. Let's think about how you might make a truly covariant and contravariant stack.
interface IPush<in T> { void Push(T item); }
interface IPop<out T> { T Pop(); }
class Stack<T> : IPush<T>, IPop<T>
{
private class Link
{
public T Item { get; private set; }
public Link Next { get; private set; }
public Link(T item, Link next) { this.Item = item; this.Next = next; }
}
private Link head;
public Stack() { this.head = null; }
public void Push(T item)
{
this.head = new Link(item, this.head);
}
public T Pop()
{
if (this.head == null) throw new InvalidOperationException();
T value = this.head.Item;
this.head = this.head.Next;
return value;
}
}
And now you can use the stack covariantly for popping, and contravariantly for pushing:
Stack<Mammal> mammals = new Stack<Mammal>();
IPop<Animal> animals = mammals;
IPush<Giraffe> giraffes = mammals;
IPush<Tiger> tigers = mammals;
giraffes.Push(new Giraffe());
tigers.Push(new Tiger());
System.Console.WriteLine(animals.Pop()); // Tiger
System.Console.WriteLine(animals.Pop()); // Giraffe
What if I want to use only one instance of B from a reference of A?
Your question is "what if I want to use a Tiger but I have a reference an Animal?" The answer is "you can't" because the Animal might not be a Tiger! If you want to test whether the reference to Animal is really a tiger then say:
Tiger tiger = myAnimal as Tiger;
if (tiger != null) ...
or
if (myAnimal is Tiger) ...
What about if you want to convert class
C<B>
toC<A>
?
That's not possible. There is no reference conversion there. The only covariant and contravariant reference conversions in C# 4 are on generic interfaces and generic delegates that are constructed with reference types as the type arguments. Generic classes and structs may not be used covariantly or contravariantly. The best thing you can do is make the class implement a variant interface.
It looks like you're using the converter simply to get a reference of type A
pointing to an object of type B
. There's a much easier way to do that, called casting:
B b = new B();
A a = (A)b;
In fact, since A is a superclass of B, the conversion is implicit:
B b = new B();
A a = b;
Your program could be:
class Program
{
static void Main(string[] args)
{
B b = new B { b1 = 22222 };
A a = b;
Console.WriteLine(a.a1);
Console.WriteLine(((B)a).b1);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With