-
Notifications
You must be signed in to change notification settings - Fork 752
Add mp_length slot for .NET classes implementing ICollection/ICollection<T> #994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Checks if the object implement ICollection or ICollection<T> - Adds tests for explicit and non-explicit interface implementation
Codecov Report
@@ Coverage Diff @@
## master #994 +/- ##
=======================================
Coverage 86.71% 86.71%
=======================================
Files 1 1
Lines 301 301
=======================================
Hits 261 261
Misses 40 40
Continue to review full report at Codecov.
|
|
||
// now look for things that implement ICollection<T> directly (non-explicitly) | ||
PropertyInfo p = clrType.GetProperty("Count"); | ||
if (p != null && clrType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too many reflections every times, you can try like this.
class Program
{
interface ICountGetter
{
int GetCount(object obj);
}
class CountGetter<Cls, T> : ICountGetter
{
private Func<Cls, int> _getter;
public CountGetter(Func<Cls, int> getter)
{
_getter = getter;
}
public int GetCount(object obj)
{
return _getter((Cls)obj);
}
}
static void Main(string[] args)
{
var obj = new MyClass();
var type = obj.GetTyp
8000
e();
var declType = type.GetInterfaces().FirstOrDefault(
t => t.IsGenericType
&& t.GetGenericTypeDefinition() == typeof(ICollection<>));
if (declType == null)
{
// set error and return
}
var pi = declType.GetProperty("Count");
var elemType = declType.GenericTypeArguments[0];
var getterType = typeof(CountGetter<,>).MakeGenericType(declType, elemType);
var getterFuncType = typeof(Func<,>).MakeGenericType(declType, typeof(int));
var getterFunc = Delegate.CreateDelegate(getterFuncType, pi.GetMethod);
var getter = (ICountGetter)Activator.CreateInstance(getterType, getterFunc);
// You should cache the ([decltype] = getter), it makes you no reflection costs when you call GetCount next time.
int count = getter.GetCount(obj);
Console.WriteLine(count);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but I feel like it would be good to have feature + tests first. It can be optimized later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@filmor good to go by me
Thanks a lot for your contribution :) |
…ion<T> (pythonnet#994) - Add mp_length slot implementation for .NET types - Check if the object implement ICollection or ICollection<T> - Add tests for explicit and non-explicit interface implementation
What does this implement/fix? Explain your changes.
Implements the mp_length slot for .NET classes that implement ICollection or ICollection, either explicitly or non-explicitly.
Does this close any currently open issues?
There are no open issues relating to this as far as I know.
Checklist
Check all those that are applicable and complete.
AUTHORS
CHANGELOG