为什么 Python.NET 使用基本方法而不是派生 class 中的方法?
Why does Python.NET use the base method instead of the method from a derived class?
编辑:这将在 pythonnet 的新版本中修复(当合并 this 拉取请求时)。
我对 Python.NET 继承有疑问。我有一个包含以下代码的 DLL:
using System;
namespace InheritanceTest
{
public class BaseClass
{
public bool Transmit()
{
throw new NotImplementedException();
}
}
public class InheritedClass: BaseClass
{
public new bool Transmit()
{
Console.WriteLine("Success!");
return true;
}
}
}
我希望调用 InheritedClass
实例的 Transmit
方法写入控制台,return true 和 Transmit
方法 BaseClass
抛出 NotImplementedException。
当运行以下python代码时:
## setup
import clr
import os
clr.AddReference(os.getcwd() + '\InheritanceTest.dll')
import InheritanceTest
## method test
base_class = InheritanceTest.BaseClass()
base_class.Transmit() # throws a NotImplementedException as expected
inherited_class = InheritanceTest.InheritedClass()
inherited_class.Transmit() # still throws a NotImplementedException, although it should call InheritedClass.Transmit
我正在使用 pythonnet 版本 2.3.0 和 .NET Framework 4.6.1。感谢您的帮助!
编辑:this question 没有回答这个问题。那里,据说
The new modifier instructs the compiler to use your child class implementation instead of the parent class implementation. Any code that is not referencing your class but the parent class will use the parent class implementation.
这显然不是这里发生的事情。
编辑 2:这似乎是 pythonnet 库的问题。 The issue is now on github.
pythonnet
方法解析(在 methodbinder.cs
文件中找到的 Bind
方法)可以改进很多恕我直言。不管怎样,这个方法目前并不真正关心类型层次结构。
一个简单的解决方案是更改 MethodSorter
class,以便在对方法进行排序以确定 Bind
调用将选择哪个方法时,派生 class 更受欢迎.
之前:
internal class MethodSorter : IComparer
{
int IComparer.Compare(object m1, object m2)
{
int p1 = MethodBinder.GetPrecedence((MethodBase)m1);
int p2 = MethodBinder.GetPrecedence((MethodBase)m2);
if (p1 < p2)
{
return -1;
}
if (p1 > p2)
{
return 1;
}
return 0;
}
}
之后:
internal class MethodSorter : IComparer
{
int IComparer.Compare(object m1, object m2)
{
var me1 = (MethodBase)m1;
var me2 = (MethodBase)m2;
if (me1.DeclaringType != me2.DeclaringType)
{
// m2's type derives from m1's type, favor m2
if (me1.DeclaringType.IsAssignableFrom(me2.DeclaringType))
return 1;
// m1's type derives from m2's type, favor m1
if (me2.DeclaringType.IsAssignableFrom(me1.DeclaringType))
return -1;
}
int p1 = MethodBinder.GetPrecedence((MethodBase)m1);
int p2 = MethodBinder.GetPrecedence((MethodBase)m2);
if (p1 < p2)
{
return -1;
}
if (p1 > p2)
{
return 1;
}
return 0;
}
}
注意我没有运行广泛的测试,所以我不确定这不会破坏其他东西。正如我所说,整个方法绑定代码似乎很脆弱。
编辑:这将在 pythonnet 的新版本中修复(当合并 this 拉取请求时)。
我对 Python.NET 继承有疑问。我有一个包含以下代码的 DLL:
using System;
namespace InheritanceTest
{
public class BaseClass
{
public bool Transmit()
{
throw new NotImplementedException();
}
}
public class InheritedClass: BaseClass
{
public new bool Transmit()
{
Console.WriteLine("Success!");
return true;
}
}
}
我希望调用 InheritedClass
实例的 Transmit
方法写入控制台,return true 和 Transmit
方法 BaseClass
抛出 NotImplementedException。
当运行以下python代码时:
## setup
import clr
import os
clr.AddReference(os.getcwd() + '\InheritanceTest.dll')
import InheritanceTest
## method test
base_class = InheritanceTest.BaseClass()
base_class.Transmit() # throws a NotImplementedException as expected
inherited_class = InheritanceTest.InheritedClass()
inherited_class.Transmit() # still throws a NotImplementedException, although it should call InheritedClass.Transmit
我正在使用 pythonnet 版本 2.3.0 和 .NET Framework 4.6.1。感谢您的帮助!
编辑:this question 没有回答这个问题。那里,据说
The new modifier instructs the compiler to use your child class implementation instead of the parent class implementation. Any code that is not referencing your class but the parent class will use the parent class implementation.
这显然不是这里发生的事情。
编辑 2:这似乎是 pythonnet 库的问题。 The issue is now on github.
pythonnet
方法解析(在 methodbinder.cs
文件中找到的 Bind
方法)可以改进很多恕我直言。不管怎样,这个方法目前并不真正关心类型层次结构。
一个简单的解决方案是更改 MethodSorter
class,以便在对方法进行排序以确定 Bind
调用将选择哪个方法时,派生 class 更受欢迎.
之前:
internal class MethodSorter : IComparer
{
int IComparer.Compare(object m1, object m2)
{
int p1 = MethodBinder.GetPrecedence((MethodBase)m1);
int p2 = MethodBinder.GetPrecedence((MethodBase)m2);
if (p1 < p2)
{
return -1;
}
if (p1 > p2)
{
return 1;
}
return 0;
}
}
之后:
internal class MethodSorter : IComparer
{
int IComparer.Compare(object m1, object m2)
{
var me1 = (MethodBase)m1;
var me2 = (MethodBase)m2;
if (me1.DeclaringType != me2.DeclaringType)
{
// m2's type derives from m1's type, favor m2
if (me1.DeclaringType.IsAssignableFrom(me2.DeclaringType))
return 1;
// m1's type derives from m2's type, favor m1
if (me2.DeclaringType.IsAssignableFrom(me1.DeclaringType))
return -1;
}
int p1 = MethodBinder.GetPrecedence((MethodBase)m1);
int p2 = MethodBinder.GetPrecedence((MethodBase)m2);
if (p1 < p2)
{
return -1;
}
if (p1 > p2)
{
return 1;
}
return 0;
}
}
注意我没有运行广泛的测试,所以我不确定这不会破坏其他东西。正如我所说,整个方法绑定代码似乎很脆弱。