我需要将以下内容添加到几个不相关的类中:
private MyClass myclass;
private EventHandler clicked;
public event EventHandler Clicked { ... }
private bool enabled;
public bool Enabled { ... }
private void HandleClicked(object sender, EventArgs e) { ... }
问题是这些类是第三方,并不一定共享相同的直接基类,尽管它们最终都从名为View
的类继承。现在,我最终为每个子类创建了自己的子类,并复制粘贴相同的代码,导致不必要的重复。
有意义地重构这个吗?
答案 0 :(得分:1)
其中一种方式是使用合成。创建将存储所有新事件\属性\方法的类:
public class Properties
{
private MyClass myclass;
private EventHandler clicked;
public event EventHandler Clicked { ... }
private bool enabled;
public bool Enabled { ... }
private void HandleClicked(object sender, EventArgs e) { ... }
}
然后使用Extension methods
扩展所需的接口(即classA)
public static class NewInterfaces
{
public static Properties Props(this classA)
{ /* lookup required properties, from some associative storage */ }
}
用法如下:
var inst = new classA();
inst.Prop.Enabled = !inst.Prop.Enabled;
第二种方式它仍然是组合,但你将使用包装器:
public class Wrapper
{
private object _wrapped;
public Wrapper(classA obj)
{
_wrapped = obj;
}
public Wrapper(classB obj)
{
_wrapped = obj;
}
public int WrappedProperty
{
get
{
var instA = _wrapped as classA;
if (instA != null)
return instA.SomeProperty1;
var instB = _wrapped as classB;
if (instB != null)
return instB.SomeProperty2;
}
}
private MyClass myclass;
private EventHandler clicked;
public event EventHandler Clicked { ... }
private bool enabled;
public bool Enabled { ... }
private void HandleClicked(object sender, EventArgs e) { ... }
}
第二种方法允许您创建新的包装器层次结构,其中包含没有公共基类的元素。
答案 1 :(得分:1)
继承在时间上变得有问题。我推荐使用接口,你会有更多的灵活性。
public interface INewInterfaces
{
event EventHandler Clicked;
bool Enabled { get; }
void HandleClicked(object sender, EventArgs e);
}
public class NewClassA : ClassA, INewInterfaces
{
//...
}
public class NewClassB : ClassB, INewInterfaces
{
//...
}
修改1:
如果你说ClassX非常相似,并且你想在所有这些不相关的类中使用相同的HandleClicked实现,你可以使用另外两种方法。
1-仍然继承
创建一个接口,并在要使用的类中添加所有常用功能。这将使ClassX成为同一个家族。然后创建一个通用的类。
public interface IExistingInterfaces
{
void SomeMethod();
}
public class NewClassA : ClassA, IExistingInterfaces
{
//Do nothing
}
public class NewClassB : ClassB, IExistingInterfaces
{
//Do nothing
}
public class MyClassForGeneralUse : IExistingInterfaces
{
private IExistingInterfaces _baseObject;
public MyClassForGeneralUse(IExistingInterfaces baseObject)
{
_baseObject = baseObject;
}
//Write proxy calls for IExistingInterfaces
public void SomeMethod()
{
_baseObject.SomeMethod();
}
//Add new methods here
public void HandleClicked(object sender, EventArgs e)
{
}
//...
//...
}
不:第一部分是Bridge Pattern,第二部分是Decorator Pattern
2-反思
var propertyInfo = someObject.GetType().GetProperty("property name");
if (propertyInfo == null)
throw new Exception(string.Format("Property does not exist:{0}", condition.Property));
var propertyValue = propertyInfo.GetValue(someObject, null);
long longValue = (long)propertyValue;
//You can get methods in a smilar manner and execute with
result = methodInfo.Invoke(methodInfo, parametersArray);
但反思可能过度。