所以我有这个大的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;
}
}
类型为obj
,Object
类型为MobileService
,属于Windows Azure移动服务库。
答案 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)
假设您的Facebook
,Twitter
和Linkedin
类继承自基类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);
}
}