在基类型" virtual"中声明方法然后使用" override"关键字在子类型中覆盖它而不是new在声明子类型中的匹配方法时简单地使用" "关键字之间有什么区别?
编辑:这将在新版本的pythonnet中修复(当合并此拉取请求时).
我有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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望调用Transmit一个实例的方法InheritedClass来写入控制台并返回true和抛出NotImplementedException 的Transmit方法BaseClass.
运行以下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 …Run Code Online (Sandbox Code Playgroud) 以前我问过一个问题没有得到充分回答,因此我决定重新制定我的问题以了解发生了什么:
这是我的类层次结构:
interface I
{
void f();
}
class A : I
{
// non virtual method
public void f()
{
Debug.Log("---->> A ");
}
}
class B : A
{
// non overriding but hiding class A method
public void f()
{
Debug.Log("---->> B ");
}
}
class C : I
{
// non virtual method
public void f()
{
Debug.Log("---->> C ");
}
}
Run Code Online (Sandbox Code Playgroud)
这是执行代码:
Random rnd = new Random();
var randomI = rnd.Next(0, 2);
I i = …Run Code Online (Sandbox Code Playgroud) 我有一个项目,我广泛使用通用的C#字典.我需要复合键,所以我一直使用元组作为键.在某些时候,我想知道使用缓存哈希码的自定义类是否有益:
public class CompositeKey<T1, T2> : Tuple<T1, T2>
{
private readonly int _hashCode;
public CompositeKey(T1 t1, T2 t2) : base(t1, t2)
{
_hashCode = base.GetHashCode();
}
public new int GetHashCode()
{
return _hashCode;
}
}
Run Code Online (Sandbox Code Playgroud)
我使用new而不是override因为我认为它对这个测试没有任何影响,因为我使用具体类型定义字典:
var dict = new Dictionary<CompositeKey<string, int>, int>();
Run Code Online (Sandbox Code Playgroud)
但是,我注意到我的自定义GetHashCode方法根本没有被调用.当我改变它时,按预期调用new了override它.
有人可以解释为什么GetHashCode不调用隐藏方法?如果我像这样定义字典,我会期待这种行为
var dict = new Dictionary<Tuple<string, int>, int>();
Run Code Online (Sandbox Code Playgroud)
但如果我CompositeKey在我的例子中明确指定了类型,则不行.
PS我知道隐藏这个GetHashCode方法可能不是一个好主意.
我的基类声明:
public double Value;
Run Code Online (Sandbox Code Playgroud)
我的派生类声明:
public new decimal Value;
Run Code Online (Sandbox Code Playgroud)
在使用关键字的提示中new,它说:“ ...Use the new keyword if hiding was intended.”。
这个解释似乎不太正确。当使用new关键字时,它并没有隐藏基变量。它使两个变量保持相同的名称,甚至具有不同的值。
我知道我这边存在设计问题,但我想知道为什么关键字并new没有真正隐藏基类变量。另外,new如果关键字意味着设计问题(更改派生类中的数据类型),为什么它甚至可用。这里使用dynamic一个选项吗?问题是:在大多数情况下,double都很好。但是在一些派生类中,它必须是decimal.
这个问题的重点是派生类中变量关键字的使用new,而不是真正讨论 double 和decimal 之间的差异。
谢谢。
我想知道是否有一种方法来覆盖派生类中具有不同类型的同名变量.有点像这样的东西(虽然这段代码不会编译):
public class A
{
public virtual Point2D Point; // Represent a 2D point
}
public class B : A
{
public override Point3D Point; // Represent a 3D point
}
Run Code Online (Sandbox Code Playgroud)
这样做的原因是,A并且B可能共享相似的属性,只是它的维度Point不同.
问题是:有两个类,A和B.
public abstract class A
{
public A()
{
Console.WriteLine("A");
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public new void Fun()
{
Console.WriteLine("B.Fun()");
}
}
Run Code Online (Sandbox Code Playgroud)
如果运行:
public void Main()
{
A a = new B();
a.Fun();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
A
B
A.Fun()
Run Code Online (Sandbox Code Playgroud)
如何解释这个结果,我知道它与抽象和成功有关,但我不知道如何解释.请帮忙.
请考虑以下代码:
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
Print(a);
Print(b);
Console.WriteLine(b.Hello);
Console.ReadLine();
}
static void Print<T>(T t) where T : A
{
Console.WriteLine(typeof(T));
Console.WriteLine(t.GetType());
Console.WriteLine(t.Hello);
}
}
public class A
{
public string Hello { get { return "HelloA"; } }
}
public class B : A
{
public new string Hello { get { return "HelloB"; } }
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出(.NET FW 4.5)
在下面的示例中,我想替换部分计算,而不必在派生子类中重新实现整个计算.
class DummyCalcBase
{
public int changeable_part()
{
return 5;
}
public int common_calculation()
{
return 5 * changeable_part();
}
}
class DummyCalc : DummyCalcBase
{
public new int changeable_part()
{
return 10;
}
}
class Program
{
static void Main(string[] args)
{
int c = new DummyCalcBase().common_calculation();
Console.WriteLine("Base gives " + c.ToString());
int c2 = new DummyCalc().common_calculation();
Console.WriteLine("Calc gives " + c2.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
然后给出输出:Base给出25 Calc给出25
我想要的是让DummyCalc().common_calculation()调用新的changeable_part(并给出答案50).
这意味着我不必将相同的方法复制并粘贴到子类中.
这里很新人,开始深入了解C#.
我想知道你是否可以"更新"一个继承的方法.在我的例子中,"Mage"类继承自"Hero".两者都有一个"Shout"方法,但Mage的喊叫应该在屏幕上添加一行文字,但我只得到Hero的一个.
我不想覆盖Hero的Shout,但是"更新它",所以Hero的孩子们可以喊出别的东西.我期待新的让我在使用它的同时修改旧方法,但没有运气.我错过了什么?
public class Hero
{
protected string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public Hero(string n)
{
Name = n;
}
public virtual void Shout()
{
Console.WriteLine("I am {0} and I am a hero! ", Name);
}
}
public class Mage : Hero
{
public Mage(string n) : base(n)
{
Name = n;
}
public new void Shout()
{
base.Shout();
// Next line does not print...
Console.WriteLine("Also, …Run Code Online (Sandbox Code Playgroud) c# ×10
inheritance ×4
overriding ×3
oop ×2
.net ×1
abstract ×1
dictionary ×1
generics ×1
interface ×1
polymorphism ×1
python ×1
python.net ×1
subclass ×1
syntax ×1