Alternative for Covariance for silverlight 4.0 IEnumerable<T> - c#

I am using silverlight 4.0 in my application. I have a method in my base class as mentioned below
class BaseClass
{
protected CustomRequest GetCustomRequest(IEnumerable<IRequestType> types)
{
//Some code here...
}
}
In my derived class when I call this method like below I get error
IEnumerable<RequestType> requestTypes = CodeToGetThis();
GetCustomRequest(requestTypes)
Note here that in calling statement the type of requestTypes is a enumerable of derived type of IRequestType.
This works well in desktop applications due to introduction of covariance in c#4.0. But it seems that for silverlight 4.0 it is not done for IEnumerable interface.
So what is the best alternative approach I should use in my silverlight application for this?
I somewhere read that it can be done using method overloading but not sure how to do this.
UPDATE:
One thing I missed in the first draft of the question is, I will have many derived types of IRequestType hence craeating overloaded method for each derived type will be a difficulty for me.

Just cast each item to the interface e.g.
IEnumerable<IRequestType> requestTypes = CodeToGetThis().Select(x => (IRequestType)x);
GetCustomRequest(requestTypes)
You could do something with method overloading and have a method that took your derived/concrete type but you would only end up doing something like the above and calling the original method in the overload.

Related

Is the invocation of a generic method allowed inside another generic method?

I'm making a RTS game with Unity. There're many types of resources in my game, such as, tree, farm. Each resource is a GameObject and has it own main script controlling it.
Ex. I want to harvest a tree, I call this.
gameObject.GetComponent<Tree>().Harvest();
If I want to harvest farm I call the same script but change "Tree" to "Farm" which is fine but code will be duplicated. So I abstract it by using generics method like this.
void Harvest<T>(){
gameObject.GetComponent<T>().Harvest();
}
But the C# compiler won't let me do that. I want to know is it possible to define generics method that use generics method inside? If not, Is there any way to abstract my code like this? Thank you.
Error message:
'T' does not contain a definition for 'Harvest' and no extension method 'Harvest' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]
The problem is that in ...
void Harvest<T>(){
gameObject.GetComponent<T>().Harvest();
}
... the C# compiler does not know of which concrete type T will be. Therefore, it cannot know that there will be a method Harvest available, nor does it know its exact declaration (does it return void or bool or something else? Does it have optional arguments?). Because C# is a strongly typed language, this must be known at compile time. This gives you the certainty that everything will go well at runtime.
The solution is to give the compiler a hint by specifying a generic type constraint. To do this you must declare an interface and let the components with a Harvest method implement it.
public interface IHarvestable
{
void Harvest();
}
Specify the constraint with:
void Harvest<T>() where T : IHarvestable
{
gameObject.GetComponent<T>().Harvest();
}
In other situations where you are in control of the base class, you can also declare the required methods in the base class (possibly as abstract) and specify the base class in the generic type constraint instead of an interface.
Define an interface for all objects that use Harvest(), then define that T extends that interface:
public interface IHarvestable
{
void Harvest();
}
// In your class:
void Harvest<T>() where T: IHarvestable
{
gameObject.GetComponent<T>().Harvest();
}
BAD alternative (mentioned just as a "hacky" addition to the answer because C# supports this - do NOT use it in practice): If you want to skip -time checking you can use dynamic:
dynamic harvestable = gameObject.GetComponent<T>();
harvestable.Harvest();
Note this is a bad practice, leading to method call resolving at runtime, leading to performance drawbacks and making your code much more error prone. For instance, usage of method from a T type instance which does not implement Harvest() will be allowed by the compiler, leading to a runtime error.

objective-c's __kindof in C#

I have no experience in objective c and am trying to translate a class written in objective c to c#. In the objective C class there is the "__kindof" keyword, such as
- (NSArray<__kindof NSViewController *> *)popToViewController:(__kindof NSViewController *)viewController animated:(BOOL)animated;
I researched about this keyword, and the documentation says that it allows NSViewController's subclass to be passed as parameter or element in the array. So I am wondering if there is a similar thing in C#. If not, are we allowed to just pass subclass of NSViewController as this method's parameter or the NSArray's element?
You are mostly talking about Inheritance by means of inheriting a abstract base class or implementing a Interface. Then you can pass in a sub-class instance in place of base-class.
Something like below:
public interface INSViewController { ... }
public class ChildNSViewController : INSViewController {... }
//Your method definition
public IEnumerable<INSViewController> popToViewController(INSViewController arg) {... }
You can call this method now with child type as parameter
popToViewController(new ChildNSViewController())
So I am wondering if there is a similar thing in C#.
Not as such. Effectively __kindof allows a cast which might fail to be omitted - hopefully because the code has done a test and knows it won't.
For example: if Y is a subclass of X and you have a variable of type X then you can test if it is a Y, cast to Y, and call a Y method. If the variable has type __kindof X then the cast step can be omitted. Objective-C however does not statically enforce the test step, relying on runtime tests to catch any error.
C# 7's pattern matching feature can be used to do something sort-of similar, in that you can test (in an if or switch) if something is of a particular type and bind a name to it as that type - so again avoid casts after the test. Unlike the Objective-C feature the test part is required.
If not, are we allowed to just pass subclass of NSViewController as this method's parameter or the NSArray's element?
Yes. In your C# code you might require casts/is/as uses that are implicit in Objective-C - unless you favour dynamic and run time tests.
HTH

Using bound interface in F#

I am trying to use C# library in F# so it would be very much specific case. I using Servicestack with F#. Now, I am trying to wire up class with interface using method
RegisterAutoWiredAs<T,'TAs>()
signature. Here is 'T is having constraint that it has to implement 'TAs. It works fine in C# code.
But F# is having constraint while using interface.
let f:IFoo = Foo() // will give type error
let fi:IFoo - Foo() :> IFoo // will work
Here Foo has implemented IFoo. So, this part is quite different than C# equivalent. Now, above signature is giving type error if I do like this
container.RegisterAutoWiredAs<Foo,IFoo>()
And there is noway to do casting while giving parameter.
Here is line from original project I am trying to run. Everything in this code works other than this part and also sadly other equivalent methods are also failing.
And here is the error I am getting in that project
This expression was expected to have type
'MemoryChatHistory' but here has type
'IChatHistory'
F# does not support implicit interface implementations.
I think you may be able to work around this in this instance by making IChatHistory an abstract class rather than an interface (using [<AbstractClass>] attribute).
EDIT:
Nope, I had a chance to play around with it today. I think it's impossible to call this method directly with those type parameters from F#. See this question
How do I translate a `where T : U` generic type parameter constraint from C# to F#?
for a little more discussion.
You might be able to work around this by using reflection to call the method.

Is it possible to perform Method Hiding without using New keyword?

Today I had an interview where I have been asked
Is it possible to perform Method Hiding without using New keyword?
As far as I know , it is not possible. So I said that.
Is there any (seriously) tricky / alternate way to perform Method Hiding? I thought of Sealed once....
Also like Explicit Interface, is there something of that sort...(not sure)
Edited
As a last question on this topic, like we can do for explicit interface
Interfacename.Method name
Can we do something similar for a derived class like.
Class Derived:Base
{
public void Base.SomeMethod(){}
}
Absolutely - if you don't specify anything, you still get the same effect as with the new modifier, but you get a warning as well.
There's also explicit interface implementation, of course.
In both cases, just casting the target to a different type "unhides" the method:
((BaseClass) x).SomeMethod();
((IFoo) x).SomeMethod();
Sealing a class has nothing to do with method hiding though - or rather, it prevents any derived classes from hiding a method, by making sure there are no derived classes.

Implementing a generic interface

I have a generic interface:
public interface IUnauthorizedRequestRespondable<out T> where T:class
{
T GetResponseForUnauthorizedRequest();
}
(I'm not sure why Resharper recommended T is "out", but that's not the question).
In my scenario, the object returned by GetResponseForUnauthorizedRequest is always of the type that implements the interface.
So all the interface's implementations look like:
public class SignInReturnedObject : IUnauthorizedRequestRespondable<SignInReturnedObject>
(class name and the type in brackets are always the same).
Which seems a bit awkward - isn't there a neater way to tell the compiler that the interface's method returns the type it's a part of?
Thanks.
As far as I know, there is no way to do that currently in C#.
A theoretical side-note: The feature that would allow you to do this is called self types but that's not available in C#. The idea of the feature is that you have a special type that refers to the actual type of this, so if you had a special type named self, you could probably write something like:
public interface IUnauthorizedRequestRespondable {
self GetResponseForUnauthorizedRequest();
}
...and the actual type used in place of self when you have a class SignInReturnedObject implementing the interface would be SignInReturnedObject, but unfortunatelly, that's not
available in C# :-)
If the only way you want to use that template is in that manner, I would use:
public interface IUnauthorizedRequestRespondable<T> where T:IUnauthorizedRequestRespondable<T>
{
T GetResponseForUnauthorizedRequest();
}
This has the advantage of guaranteeing it isn't used in any other way.
The class declaration won't change, but I don't see anything as awkward in this myself. Considering that you are defining a relationship between the class and itself, any more concise form might be inadvisable.
Actually, that about sums it up. That is how the syntax works.
You can see it used in .NET itself with the IEquatable inteface--you are almost always comparing an object to itself, yet you always have to provide your own class name as a template parameter.
This is simply to provide flexibility such that you can compare to anything, not necessarily yourself.
You can create a nongeneric version and just use that but I think it is more trouble than it is worth
public interface ICastUnauthorizedRequestRespondable : IUnauthorizedRequestRespondable<SignInReturnedObject>
{
}
Since T can be any class (does not have to be the class you are implementing) you need to name your class.
public class SignInReturnedObject : IUnauthorizedRequestRespondable<ANYCLASS>

Categories

Resources