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 的类。现在,我最终为每个子类创建了自己的子类,并复制粘贴了相同的代码,这会导致不必要的重复。

有什么方法可以有意义地重构它吗?

C#:在不相关的类之间共享属性、事件和方法

其中一种方法是使用组合。创建将存储所有新事件''属性''方法的类:

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);

但反思可能是矫枉过正。