Using bound interface in F# - c#

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.

Related

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

C# object in IronPython: expected interface, got implementation

Well, here is a problem:
I have a part of .NET code, translated into IronPython. This code refers to other .NET code (don't ask why). C# method takes c#-written interface as parameter, f.e.
public int SomeMethod(ISomeInterface instance)
in IronPython I try to call this method from dll, like this:
someValue = SharpClass.SomeMethod(self.InheritedProperty)
self.InheritedPropertyhas type - implementation of ISomeInterface. Let suppose "SomeInterfaceImpl"
And I got runtime error:
expected ISomeInterface, got SomeInterfaceImpl
How to avoid this? I cannot do cast in python, because of abstract interface.

Get method's implementation with Roslyn

If for example, I declare an interface class whose actual class type will only be determined on runtime, and by using VisualStudio when I right click the method call and click "Go To Implementation" I can find 3 implementations from classes that inherits the interface.
How can I, using Roslyn, get the method's implementation syntax nodes/symbols?
You're looking for SymbolFinder.FindImplementationsAsync.
Just look at the code that implements Go To Implementation. There's several public APIs on the SymbolFinder type that give you overrides/implementations/derived types, and each give you symbols back. Most of the code in the feature is just figuring out which is the right method to call, with some extra filtering that's specific for the feature. For example, if you have a derived type that's got an abstract member, the core functions will return that method, but it's not an implementation in a meaningful way for the sake of the feature.

Alternative for Covariance for silverlight 4.0 IEnumerable<T>

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.

Can a class inherit from LambdaExpression in .NET? Or is this not recommended?

Consider the following code (C# 4.0):
public class Foo : LambdaExpression { }
This throws the following design-time error:
Foo does not implement inherited abstract member
System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller)
There's absolutely no problem with public class Foo : Expression { } but, out of curiosity and for the sake of learning, I've searched in Google System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) and guess what: zero results returned (when was the last time you saw that?). Needless to say, I haven't found any documentation on this method anywhere else.
As I said, one can easily inherit from Expression; on the other hand LambdaExpression, while not marked as sealed (Expression<TDelegate> inherits from it), seems to be designed to prevent inheriting from it. Is this actually the case? Does anyone out there know what this method is about?
EDIT (1): More info based on the first answers - If you try to implement Accept, the editor (C# 2010 Express) automatically gives you the following stub:
protected override Expression Accept(System.Linq.Expressions.ExpressionVisitor visitor)
{
return base.Accept(visitor);
}
But you still get the same error. If you try to use a parameter of type StackSpiller directly, the compiler throws a different error: System.Linq.Expressions.Compiler.StackSpiller is inaccessible due to its protection level.
EDIT (2): Based on other answers, inheriting from LambdaExpression is not possible so the question as to whether or not it is recommended becomes irrelevant. I wonder if, in cases like this, the error message should be Foo cannot implement inherited abstract member System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) because [reasons go here]; the current error message (as some answers prove) seems to tell me that all I need to do is implement Accept (which I can't do).
I just looked at the LambdaExpression class in .NET 3.5 using Reflector and the class has only an internal constructor. When I try your code, I'm getting an error "The type 'System.Linq.Expressions. LambdaExpression' has no constructors defined", so on .NET 3.5 this cannot be done (leaving aside the question whether it would be useful to do it).
In .NET 4.0 it behaves as you described. However, the Accept method is internal and so is the StackSpiller type. This again means that you simply can't do this (although it isn't clear from the compiler error message). It is worth noting that the class still has only internal constructor on .NET 4.0. The compiler only finds another reason why you can't override it (and doesn't worry about that any more).
EDIT: Regarding the StackSpiller type - it is internal, so you don't really need to worry about it. However, it looks that the type comes from DLR, which is a .NET 4.0 component that now handles compilation of lambda expressions (and also C# 4 dynamic). Anyway, DLR is open-source, so here is what a summary comment says about this type:
Expression rewriting to spill the CLR stack into temporary variables
in order to guarantee some properties of code generation, for
example that we always enter try block on empty stack.
This means that it is used to do some pre-processing of lambda expressions when they are compiled using the Compile method. You can get the source code from CodePlex.
The error message means that LambdaExpression itself is an abstract class. You need either supply your body for abstract method Accept, or declare Foo as abstract.
However, list of LambdaExpression members on MSDN doesn't list Accept.
Well, the error basically tells us that LambdaExpression is an abstract class, which means that in order to derive from it, you'd have to implement all abstract members. In this case, the Accept method.
It is neither recomended or allowed. The LambdaExpression type has several internal abstract members and an internal constructor. This prevents you from deriving from it from a different assembly unless their is a friend relationship (which there is not in this case)

Categories

Resources