Рефакторинг дженериков C#

В то время как, решая, какие символы позволяются, помните свой apostrophed и написанных через дефис друзей. Я не имею никакого контроля над тем, что моя компания генерирует мой адрес электронной почты с помощью моего имени от системы HR. Это включает апостроф в мою фамилию. Я не могу сказать Вам, сколько раз я был заблокирован от взаимодействия с веб-сайтом тем, что мой адрес электронной почты "недопустим".

6
задан Russell Giddings 7 August 2009 в 10:43
поделиться

3 ответа

Попробуйте использовать шаблонную функцию. Он должен определять тип на основе типа передаваемого вами параметра, поэтому вам не нужно явно указывать тип в вызове 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);
     }
2
ответ дан 17 December 2019 в 20:34
поделиться

Вы можете использовать приведение для решения проблемы присваивания. Если 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();
  }

}
0
ответ дан 17 December 2019 в 20:34
поделиться

Что насчет этого?

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>();
}
0
ответ дан 17 December 2019 в 20:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: