8000 Add mp_length slot for .NET classes implementing ICollection/ICollection<T> by slide · Pull Request #994 · pythonnet/pythonnet · GitHub
[go: up one dir, main page]

Skip to content

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

Merged
merged 10 commits into from
Dec 16, 2019
Merged

Conversation

slide
Copy link
Contributor
@slide slide commented Nov 21, 2019

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.

  • Make sure to include one or more tests for your change
  • If an enhancement PR, please create docs and at best an example
  • Add yourself to AUTHORS
  • Updated the CHANGELOG

@codecov-io
Copy link
codecov-io commented Nov 21, 2019

Codecov Report

Merging #994 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #994   +/-   ##
=======================================
  Coverage   86.71%   86.71%           
=======================================
  Files           1        1           
  Lines         301      301           
=======================================
  Hits          261      261           
  Misses         40       40
Flag Coverage Δ
#setup_linux 65.44% <ø> (ø) ⬆️
#setup_windows 71.42% <ø> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5f56ebc...f4fb3cb. Read the comment docs.


// 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<>)))
Copy link
Member

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.GetType();
            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);
        }
    }

Copy link
Member
@lostmsu lostmsu Nov 21, 2019

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.

Copy link
Member
@lostmsu lostmsu left a 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

@filmor filmor merged commit ba5127a into pythonnet:master Dec 16, 2019
@filmor
Copy link
Member
filmor commented Dec 16, 2019

Thanks a lot for your contribution :)

AlexCatarino pushed a commit to QuantConnect/pythonnet that referenced this pull request Jun 27, 2020
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0