我有几个类看起来像下面的那个,我需要在get方法和自定义set方法中做一些检查。在每个get和set方法中添加代码会使一切看起来都搞砸了。
有没有办法可以覆盖整个类中所有属性的get和set方法?
public class Test
{
private DataRow _dr;
public Test()
{
_dr = GetData();
}
public string Name
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string Description
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string DescriptionUrl
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
}
}
private void VerifyAccess(string propertyname, string classname)
{
//some code to verify that the current user has access to update the property
//Throw exception
}
private DataRow GetData()
{
//Some code to pull the data from the database
}
}
答案 0 :(得分:1)
不是直接的,只有一个编译器没有办法做到这一点。您必须生成整个二进制文件,然后使用一些外部工具对其进行后处理。
This post描述了一个类似的问题;我希望它有所帮助。
答案 1 :(得分:1)
我认为您需要的是您课堂上的 Proxy
,请阅读 Proxy Pattern
和 Dynamic Proxies
< / em>的
答案 2 :(得分:1)
有多种方法可以做到这一点。 一种方法是创建一个代理类(前面提到过),但这需要代表你进行大量的重构。 另一种方式是方面。这些正是您所追求的(根据先决条件插入代码,即从x继承的类中的所有get方法)。我遇到了类似的问题(实际上是完全相同的问题 - 检查方法调用的安全性),并且找不到满足我需求的廉价/免费方面软件。
所以,我决定在函数调用之前使用Mono-Cecil注入代码。
如果你感兴趣(处理IL代码有点乱)我可以发布源代码的旧副本
答案 3 :(得分:0)
您应该提取公共代码以分离get / set方法,之后您将能够向属性添加公共逻辑。顺便说一下,无论如何我都会进行这样的提取以避免代码中的复制/粘贴。
像这样的Smth:public string Name
{
get { return GetProperty(MethodBase.GetCurrentMethod()); }
set
{
SetProperty(MethodBase.GetCurrentMethod(), value);
}
}
private string GetProperty(MethodBase method)
{
return _dr[method.Name.Substring(4)].ToString();
}
private void SetProperty(MethodBase method, string value)
{
string methodName = method.Name.Substring(4);
VerifyAccess(methodName , this.GetType().Name);
_dr[methodName] = value;
}
答案 4 :(得分:0)
这可以通过间接价值访问来完成,例如: obj.PropA.Value = obj.PropB.Value + 1
- 您甚至可以保留强大的输入信息。它可以使用属性或直接实例化来实现。
// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;
// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);
或者,也许使用诸如TT4的模板系统可能是可行的方法。
但是,不要忘记“KISS”: - )
答案 5 :(得分:0)
我希望有人能为此提供更好的答案。
我现在正在寻找答案...我最好的想法是定义你想要被验证为通用类的所有属性。例如:
public class Foo {
public String Name {
get{ return _Name.value; }
set{ _Name.value = value; }
}
private Proxy<String> _Name;
static void main(String[] args) {
Foo f = new Foo();
//will go through the logic in Proxy.
f.Name = "test";
String s = f.Name;
}
}
public class Proxy<T> {
public T value {
get {
//logic here
return _this;
} set {
//logic here
_this = value;
}
}
private T _this;
}