簡體   English   中英

C#泛型重構

[英]C# Generics Refactoring

我試圖重構一段似乎很容易重構的代碼,但事實證明很難。 有兩種方法看起來非常相似,我覺得應該重構: -

public class MyClass
{
    private void AddBasicData(Receiver receiver)
    {
        var aHelper = new AHelper();
        var bHelper = new BHelper();
        var cHelper = new CHelper();
        receiver.ObjA = aHelper.GetBasic();
        receiver.ObjB = bHelper.GetBasic();
        receiver.ObjC = cHelper.GetBasic();
    }

    private void AddExistingData(Receiver receiver)
    {
        var aHelper = new AHelper();
        var bHelper = new BHelper();
        var cHelper = new CHelper();
        receiver.ObjA = aHelper.GetExisting();
        receiver.ObjB = bHelper.GetExisting();
        receiver.ObjC = cHelper.GetExisting();
    }
}

這個類的參考代碼在這里......

public class AHelper : Helper<A> 
{
}

public class BHelper : Helper<B> 
{
}

public class CHelper : Helper<C> 
{
}

public class Helper<T> : IHelper<T> where T : IMyObj
{
    public T GetBasic()
    {
       ...
    }

    public T GetExisting()
    {
       ...
    } 
}

public interface IHelper<T>
{
    T GetBasic();
    T GetExisting();
}

public class A : IMyObj {}
public class B : IMyObj {}
public class C : IMyObj {}

public interface IMyObj {}

public class Receiver
{
    public A ObjA { get; set; }
    public B ObjB { get; set; }
    public C ObjC { get; set; }
}

我的第一次嘗試是像這樣重構......

public class MyClass
{
    private void AddBasicData(Receiver receiver)
    {
        Func<Helper<IMyObj>, IMyObj> func = x => x.GetBasic();
        AddData(receiver, func);
    }

    private void AddExistingData(Receiver receiver)
    {
        Func<Helper<IMyObj>, IMyObj> func = x => x.GetExisting();
        AddData(receiver, func);
    }

    private void AddData(Receiver receiver, Func<Helper<IMyObj>, IMyObj> func)
    {
        var aHelper = new AHelper();
        var bHelper = new BHelper();
        var cHelper = new CHelper();
        receiver.ObjA = func(aHelper);
        receiver.ObjB = func(bHelper);
        receiver.ObjC = func(cHelper);
    }
}

這個問題是new AHelper()不能分配給Helper<IMyObj> :-(

任何人都可以看到這可以很好地重構?

提前致謝

羅素

嘗試使用模板化功能。 它應該根據您傳遞的參數類型推斷類型,因此您不需要在AddData調用中顯式指定類型。

public class MyClass
{

  private void AddData<T>(Receiver receiver, Func<Helper<T>, T> func)
  {
     var aHelper = new AHelper();
     var bHelper = new BHelper();
     var cHelper = new CHelper();
     receiver.ObjA = func(aHelper);
     receiver.ObjB = func(bHelper);
     receiver.ObjC = func(cHelper);
  }
}

嘗試#2:棘手的問題我認為你需要一個更通用的IHelper接口。 這樣的事情有幫助嗎?

public interface IHelper
{
   IMyObj GetBasic();
   IMyObj GetExisting();
}

public interface IHelper<T> : IHelper
{
   T GetBasic();
   T GetExisting();
}

你必須弄清楚派生界面和基礎界面之間的名稱沖突,但我不確定你是怎么想這樣做的,而且我已經沒時間了,所以我會留下那個就目前而言。

嘗試#3(我決心得到這個!):這會是作弊嗎?

  public enum RetrievalMethod
  {
     Basic,
     Existing
  }
  public class Helper<T> : IHelper<T> where T : IMyObj
  {

     public T Get(RetrievalMethod rm)
     {
        switch(rm)
        {
           case RetrievalMethod.Basic:
              return GetBasic();
           case RetrievalMethod.Existing:
              return GetExisting();
        }
     }
...
  }
...
     private void AddData(Receiver receiver, RetrievalMethod rm)
     {
        var aHelper = new AHelper();
        var bHelper = new BHelper();
        var cHelper = new CHelper();
        receiver.ObjA = aHelper.Get(rm);
        receiver.ObjB = bHelper.Get(rm);
        receiver.ObjC = cHelper.Get(rm);
     }

您可以使用強制轉換來解決分配問題。 如果AHelper實際上返回A,我認為這是有效的

private void AddData(Receiver receiver, Func<Helper<IMyObj>, IMyObj> func)
    {
        var aHelper = new AHelper();
        var bHelper = new BHelper();
        var cHelper = new CHelper();
        receiver.ObjA = (A) func(aHelper);
        receiver.ObjB = (B) func(bHelper);
        receiver.ObjC = (C) func(cHelper);
    }

如果你重寫方法,你可以做轉換,不需要改變“Func,IMyObj>”的定義

public class AHelper : Helper<A> 
{
  public override A GetBasic()
  {
    return new A();
  }

}

那這個呢?

private static T GetData<T, THelper>(Func<THelper, T> func) 
    where THelper : Helper<T>, new() 
    where T : IMyObj
{ return func(new THelper()); }

private static T GetBasicData<T, THelper>() 
    where THelper : Helper<T>, new() 
    where T : IMyObj
{ return GetData(x => x.GetBasic()); }

private static T GetExistingData<T, THelper>() 
    where THelper : Helper<T>, new() 
    where T : IMyObj
{ return GetData(x => x.GetExisting()); }

private void AddBasicData(Receiver receiver)
{
    receiver.ObjA = GetBasicData<A, AHelper>();
    receiver.ObjB = GetBasicData<B, BHelper>();
    receiver.ObjC = GetBasicData<C, CHelper>();
}

private void AddExistingData(Receiver receiver)
{
    receiver.ObjA = GetExistingData<A, AHelper>();
    receiver.ObjB = GetExistingData<B, BHelper>();
    receiver.ObjC = GetExistingData<C, CHelper>();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM