如何使用反射重构重复的代码

时间:2015-06-11 03:06:43

标签: c# linq generics azure reflection

所以我有这个大的switch语句,它基本上是重复多次重复的代码,其中唯一改变的是对特定类的强制转换。我一直试图找出一种使用反射重构它的方法,所以我只需要写一次。

FinishBreakpoint

请注意,switch(provider) { case SocialNetworks.Linkedin: { List<Linkedin> profiles = await MobileService.GetTable<Linkedin>().Where(p => p.uuid == (obj as Linkedin).uuid).ToListAsync(); if (profiles.Count == 0) { await MobileService.GetTable<Linkedin>().InsertAsync(obj as Linkedin); } break; } case SocialNetworks.Facebook: { List<Facebook> profiles = await MobileService.GetTable<Facebook>().Where(p => p.uuid == (obj as Facebook).uuid).ToListAsync(); if (profiles.Count == 0) { await MobileService.GetTable<Facebook>().InsertAsync(obj as Facebook); } break; } case SocialNetworks.Twitter: { List<Twitter> profiles = await MobileService.GetTable<Twitter>().Where(p => p.uuid == (obj as Twitter).uuid).ToListAsync(); if (profiles.Count == 0) { await MobileService.GetTable<Twitter>().InsertAsync(obj as Twitter); } break; } } 类型为objObject类型为MobileService,属于Windows Azure移动服务库。

3 个答案:

答案 0 :(得分:1)

您可以通过创建接受泛型类型参数的函数来解决此问题,而无需使用反射。一个简单的例子是:

NSArray *noDuplicatesDates = [dates valueForKeyPath:@"@distinctUnionOfObjects.self"];

然后称之为:

public List<T> SomeFunction<T>()
{
    return new List<T>();
}

答案 1 :(得分:1)

回答原始问题如何使用反射以通用方式重写此方法,因此该方法不应要求对每个新社交网络进行更改。

如果要处理MySpace,您只需将其添加到 handlerMapping ,HandleAnySocialNetworkByMapping()不会更改(请参阅下面的代码)。

class Program
{
    private readonly static Dictionary<SocialNetworks, Type> handlerMapping = new Dictionary<SocialNetworks, Type>()
                                                          {
                                                              {SocialNetworks.Linkedin, typeof(Linkedin)},
                                                              {SocialNetworks.Facebook, typeof(Facebook)},
                                                              {SocialNetworks.Twitter, typeof(Twitter)},
                                                          };
    static void Main(string[] args)
    {
        HandleAnySocialNetworkByMapping(SocialNetworks.Facebook, new Facebook()).Wait();
        HandleAnySocialNetworkByMapping(SocialNetworks.Linkedin, new Linkedin()).Wait();
        HandleAnySocialNetworkByMapping(SocialNetworks.Twitter, new Twitter()).Wait();
    }

    private async static Task HandleAnySocialNetworkByMapping(SocialNetworks provider, object socialNetwork)
    {
        Type handler = handlerMapping[provider];
        var insertIfNotExistsMethodInfo = typeof(SocialRepository)
            .GetMethods()
            .First(m => m.Name == "InsertIfNotExists");
        await (Task)insertIfNotExistsMethodInfo.MakeGenericMethod(handler).Invoke(new SocialRepository(), new[] { socialNetwork });  
    }
}

,其中 SocialRepository 保持持久性逻辑

public class SocialRepository
{
    public async Task InsertIfNotExists<TEntity>(TEntity obj) where TEntity : Social
    {
        var profile = await MobileService.GetTable<TEntity>().FirstOrDefault(p => p.uuid == obj.uuid);
        if (profile == null)
        {
            await MobileService.GetTable<TEntity>().InsertAsync(obj);
        }
    }
}

<强>实体

    public abstract class Social { public Guid uuid { get; private set; } }    
    public class Linkedin : Social{/*...*/}
    public class Twitter : Social{/*...*/}    
    public class Facebook : Social{/*...*/}

    public enum SocialNetworks
    {
        Linkedin,
        Facebook,
        Twitter
    }

答案 2 :(得分:0)

假设您的FacebookTwitterLinkedin类继承自基类SocialNetwork,则此类内容应该有效。

void FunctionX(SocialNetworks provider, object obj)
{
    switch(provider)
    {
               case SocialNetworks.Linkedin:
                    {
                        FunctionY<Linkedin>(obj as Linkedin);
                        break;
                    }
                case SocialNetworks.Facebook:
                    {
                        FunctionY<Facebook>(obj as Facebook);
                        break;
                    }
                case SocialNetworks.Twitter:
                    {
                        FunctionY<Twitter>(obj as Twitter);
                        break;
                    }
    }
}

void FunctionY<T>(SocialNetwork obj)
{
    List<T> profiles = await MobileService.GetTable<T>().Where(p => p.uuid == (obj).uuid).ToListAsync();
    if (profiles.Count == 0)
    {
        await MobileService.GetTable<T>().InsertAsync(obj);
    }
}