efaruk efaruk - 11 days ago 5
C# Question

dotnet-core could not found base Interface method

I'm facing really odd situation, if i tried in VS 2015 it navigates base symbol method without any problem.Even VS Code with Omnisharp on Ubuntu 16.04 has no problem to navigate to method. But when i run, it simply throws some odd exception. I'm %100 sure method is there...

Here is dotPeek Screenshot for /Yakari.Tests/{outputdir}/Yakari.dll

Screenshot

Here is the structure:

public interface ICacheProvider : IDisposable
{
.....
void Set(string key, object value, TimeSpan expiresIn, bool isManagerCall = false);
.....
}


public interface ILocalCacheProvider : ICacheProvider
{
....
}


public abstract class BaseCacheProvider : ICacheProvider
{
.....
public abstract void Set(string key, object value, TimeSpan expiresIn, bool isManagerCall = false);
.....
}


public class LittleThunder : BaseCacheProvider, ILocalCacheProvider
{
.....
public override void Set(string key, object value, TimeSpan expiresIn, bool isManagerCall = false)
{
....
}
.....
}


When we do something like this:

public class SomeTestClass {

ILocalCacheProvider _localCacheProvider;

public SomeTestClass(ILocalCacheProvider localCacheProvider) {
_localCacheProvider = localCacheProvider;
}

public void SomeTestMethod() {
// Below line throws: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 'Yakari.ILocalCacheProvider' does not contain a definition for 'Set'
_localCacheProvider.Set("key", dynamic value, CacheTime.FifteenMinutes);
}
}


Step's to reproduce:


  1. clone https://github.com/TitaniumSoft/yakari

  2. build and run tests (You should have redis instance on your local
    host or change config how you wish)



Note: You can see same runtime error at appveyor CI Log

Any ideas ?
Thanks and regards...

Answer

The error you're getting in GreatEagle.cs:line 201 is because you're making an interface call with something typed as "dynamic" passed as a parameter. If a "dynamic" variable is involved, interface dispatch becomes very complicated, reflection-based, and slow.

So for InMemoryCacheItem.ValueObject: why is the property typed as "dynamic"? From a brief search in your repo, you might as well type it as "object" and avoid all the RuntimeBinder pains since you're casting it everywhere anyway. Or at least do a cast to object before you pass it to Set().

Comments