Skip to content

Unable to modify C# List<T> #1153

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

Closed
jfu334 opened this issue May 25, 2020 · 13 comments
Closed

Unable to modify C# List<T> #1153

jfu334 opened this issue May 25, 2020 · 13 comments

Comments

@jfu334
Copy link

jfu334 commented May 25, 2020

Environment

  • Pythonnet version: 2.4.0
  • Python version: 3.6
  • Operating System: windows 10

Details

I have a C# class like this:

public class X
{
  public List<string> list;
}

I'm unable to do useful stuff with X.list due to the automatic value conversion of pythonnet.

Preface:

pylist=["a", "b", "c"]
x=X()
x.list=System.Collections.Generic.List[str]()

Doesnt work:

x.list=System.Collections.Generic.List[str](pylist)

Doesnt work:

for i in pylist:
  x.list.Add(i)

Doesnt work:

for i in pylist:
  x.list.append(i)

x.list is always empty except for the .Add call, with throws Exception cause the value is converted to python list. How do I modify a C# List in python?

@filmor
Copy link
Member

filmor commented May 25, 2020

The .Add call works. What is the exact error you get there?

@jfu334
Copy link
Author

jfu334 commented May 25, 2020

AttributeError: 'list' object has no attribute 'Add'

@filmor
Copy link
Member

filmor commented May 25, 2020

And you are absolutely certain that X is indeed an object of your C# class?

@jfu334
Copy link
Author

jfu334 commented May 25, 2020

Yes absolutely sure. I'd guess the detail here is that the List is retrieved through accessing the field of X.

@jfu334
Copy link
Author

jfu334 commented May 25, 2020

... confirmed. The code:

l=System.Collection.Generic.List[str]()
l.Add(...)

works. But not for x.list. So at least I have a workaround.

@filmor
Copy link
Member

filmor commented May 25, 2020

Yes, you are right. There is some work going on to make these conversions optional. @lostmsu Could you chime in on how to exactly do that in this situation?

@jfu334
Copy link
Author

jfu334 commented May 25, 2020

Thanks for the fast response!

@lostmsu
Copy link
Member

lostmsu commented May 26, 2020

@jfu334 sorry for late response. You should check out the new test for RawProxyEncoder.
Mind the __namespace__ element in the code class definition.

@koliyo
Copy link

koliyo commented Mar 8, 2021

So if I understand correctly, the #1122 pull request allows the workaround with the local list l, but still not possible to call x.list.Add(...)

Any update on if this should be expected to be fixed, or is the solution unknown for this use case?

@lostmsu
Copy link
Member

lostmsu commented Mar 9, 2021

No, it should work in the x.list.Add(...) scenario.

@richard-gemmell-42
Copy link

First of all, I'd like to say that this project is awesome and I really appreciate the work that you've all put into it. Thanks.

The automatic conversion from IList'1 to a native python list causes another problem for us. There isn't a matching conversion from a native python list to an IList'1 so you can't 'round trip' a property value like this:

  values = x.List
  x.List = values  # fails as value is the wrong type

If x.List is declared to be of type IList rather than List then the behaviour is even more baffling. The value returned by x.List now depends on the type of the concrete object assigned to List and not the function prototype. If I assign a List to it then I get a python list back but if I assign a custom class which implements IList to it then I don't. This means that I can't tell the user what type of object to expect when the call x.List.

The design would be less surprising if:

  • conversions were always bi-directional (List <==> python list and vice versa)
  • the conversion depends on the function being called not on the concrete type of the objects involved

I appreciate that it's probably difficult to change the design at this point but I thought I'd point it out.

In the mean time, I'm trying to use a RawProxyEncoder to disable the conversion from List. Unfortunately this triggers a stack overflow. Please see the link to issue #1427 above.

I wasn't sure these comments were worth another ticket so I thought I'd add them here. Please let me know if you think I should raise another ticket.

cheers,
Richard

@lostmsu
Copy link
Member

lostmsu commented Mar 30, 2021

@richard-gemmell-42 I actually have a better design in my company's fork: when seen from Python .NET collection types have extra base classes (aka mixins), that implement Pythonic members using .NET members. See for example

https://github.com/losttech/pythonnet/blob/cae2d32729a35fb31f53fd694464f5c44392b896/src/runtime/Mixins/collections.py#L36

I am planning to upstream that feature before 3.0 is released.

@lostmsu
Copy link
Member

lostmsu commented Sep 23, 2021

C# Lists are no longer automatically converted to Python list in Python.NET 3.0, but still behave like list does.

@lostmsu lostmsu closed this as completed Sep 23, 2021
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

No branches or pull requests

5 participants