C#:在不相关的类之间共享属性、事件和方法
本文关键字:属性 事件 方法 共享 之间 不相关 | 更新日期: 2023-09-27 18:35:06
我需要将以下内容添加到几个不相关的类中:
private MyClass myclass;
private EventHandler clicked;
public event EventHandler Clicked { ... }
private bool enabled;
public bool Enabled { ... }
private void HandleClicked(object sender, EventArgs e) { ... }
问题是这些类是第三方的,不一定共享相同的直接基类,尽管它们最终都继承自名为 View
的类。现在,我最终为每个子类创建了自己的子类,并复制粘贴了相同的代码,这会导致不必要的重复。
有什么方法可以有意义地重构它吗?
其中一种方法是使用组合。创建将存储所有新事件''属性''方法的类:
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
扩展所需的接口(即 A类)
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) { ... }
}
第二种方法允许您创建新的包装器层次结构,该层次结构将包含没有公共基类的元素。
继承在时间上变得有问题。我建议改用接口,您将拥有更大的灵活性。
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)
{
}
//...
//...
}
Not:第一部分是桥接模式,第二部分是装饰器图案
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);
但反思可能是矫枉过正。