C#:跨不相关的类共享属性,事件和方法

时间:2016-02-18 07:10:30

标签: c# oop events

我需要将以下内容添加到几个不相关的类中:

private MyClass myclass;

private EventHandler clicked;
public event EventHandler Clicked { ... }

private bool enabled;
public bool Enabled { ... }

private void HandleClicked(object sender, EventArgs e) { ... }

问题是这些类是第三方,并不一定共享相同的直接基类,尽管它们最终都从名为View的类继承。现在,我最终为每个子类创建了自己的子类,并复制粘贴相同的代码,导致不必要的重复。

有意义地重构这个吗?

2 个答案:

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

但反思可能过度。