我想知道是否有人在调用子属性方法时,它也会调用父属性。 请注意,子代是由edmx的代码生成器生成的。因此,除了为子类添加部分类之外,我无法更改任何内容。 (改变发电机可能太麻烦了。)
我遇到的情况: 我有一个“MyClass”类,它是从数据库自动生成的。除了添加部分类或更改代码生成器之外,我无法对其进行任何更改。
现在,每当调用属性Name时,我都需要“做某事”。我正在考虑是否可以将父母放在那里,并在调用子属性“名称”时让父母调用父母做“某事”。
我想要的是什么:
public class ClassBase
{
public string Name
{
get
{
CallMethod();
return Name;
}
}
}
public class MyClass : ClassBase
{
public string Name { get; set; }
}
MyClass myClass = new MyClass();
myClass.Name; < -- this will call the parent as well.
无论如何都要这样做?
提前致谢
答案 0 :(得分:1)
并不是真正相关,但由于您没有在ClassBase中严格使用自动属性,因此应为Name
创建一个私有字符串变量。类似于_name
或内部编码标准所规定的内容。
public class ClassBase
{
private string _name;
public virtual string Name
{
get
{
CallMethod();
return _name;
}
set
{
_name = value;
}
}
}
public class MyClass : ClassBase
{
//Pretty pointless really since you're not doing anything with MyClass.Name.
public new string Name
{
get
{
return base.Name;
}
set
{
base.Name = value;
}
}
MyClass myClass = new MyClass();
myClass.Name; <-- this will call the parent as well.
答案 1 :(得分:0)
基于“无法更改基类”注释,你可以做很多事情来使代码在基类之前/之后/之后执行,因为当你的新类使用时你的属性/方法不会被调用作为基类(参见详细部分中的示例)。
潜在的解决方案:如果你需要扩展专门设计的parital
类,并且它提供了像CallMethod
这样的扩展poinst标记为partial - 它应该用于实现类的部分实现它:
partial public class ClassBase
{
partial void CallMethod();
public string Name {get {CallMethod(); return "";}}
}
// in generated portion of "ClassBase"
partial public class ClassBase
{
partial void CallMethod() { /* do something here */ }
}
回答以确切地说“如何调用基类属性”是使用base
,但是以这种方式隐藏属性/方法会让人感到困惑(见下文):
new public string Name { get { return base.Name;} }
请注意,您不能在派生类的情况下使用自动属性,因为您明确需要执行一些其他代码。如果在派生类中需要set
,则需要自己的支持字段,如:
private string derivedName;
new public string Name {
get { return base.Name + derivedName;}
set { derivedName = value;}
}
<强>详细信息:强>
正如在评论中所说,隐藏基类的属性/方法会导致非常混乱的行为。对于你的情况(稍微更新的基类与烘焙领域作为原始样本具有无限递归):
public class ClassBase
{
private string name;
public string Name
{
get
{
CallMethod();
return name;
}
}
}
您可以尝试在派生类中隐藏Name
属性:
public class MyClass : ClassBase
{
// notice "new" to show comiler you know what you doing
// otherwise you'll get warning (but behavior will be the same)
new public string Name { get; set; }
}
隐藏的问题是基类的方法仍然很容易调用,如果使用派生类作为基类,可能会被错误地调用:
MyClass myDerved = new MyClass();
ClassBase myDervedAsBase = myDerved;
var name = myDerived.Name; // calls MyClass.Name
var name = myDerivedAsBase.Name; // calls ClassBase.Name
这可以通过创建基类'method / property virtual
来解决 - 但它需要在基类中进行更改:
public class ClassBase
{
virtual public string Name { get {... } }
}
public class MyClass : ClassBase
{
override public string Name { get { ... } }
}
如果需要从派生类调用基类的方法/属性,请使用base.MethodName()
,如:
override public string Name { get
{
// do some new stuff here
var baseName = base.Name;
// maybe even change result
return baseName;
}
}
如果您希望大多数派生类需要这样的行为,那么明确设计基类以强制执行此类行为可能会更好。例如,您可以在计算要返回的值之前/之后调用虚方法的属性,如:
public class ClassBase
{
virtual protected string AboutToReturnName(string result)
{
return name;
}
public string Name
{
get
{
var result = "MyName";
return AboutToReturnName(result);
}
}
}
更多想法:
virtual
的替代方法是partial
方法,而不是派生类的方法是从ASP.Net页面等许多“部分”部分组合而成的 - 请参阅Partial Classes and Methods INotifyPropertyChange
答案 2 :(得分:0)
如果不修改代码生成器,则无法执行此操作。修改必须生成一个呼叫base.Name
。
答案 3 :(得分:-1)
您可以使用new运算符覆盖子类中的属性。
public class MyClass : ClassBase
{
public new string Name { get; set; }
}