如何在“可能”类型的对象之间切换?

可能重复:
C# – “开启类型”有比这更好的选择吗?

我公司的遗留代码如下

public override Uri GetUri(object obj) { if ((obj is Entry) || (obj is EntryComment)) { // } if (obj is Blog) { // } // if obj is blah blah blah } 

这种方法很难看。 我想重构它,但我不知道迭代obj可能的“可能”类型的技术。

我怎么能重构这个?

谢谢。

您也可以使用接口重构它

 public interface IHasUri { public Uri GetUri(); } 

并在所有层次结构中实现此接口。 比你可以使用

 public Uri GetUri(object obj) { IHasUri hasUri = obj as IHasUri; if(hasUri != null) Uri uri = hasUri.GetUri(); // bla bla bla } 

有两种选择:

  • 如果您使用的是C#4,则可以使用动态类型,并将方法拆分为多个重载:

     public Uri GetUri(dynamic obj) { return GetUriImpl(obj); } private Uri GetUriImpl(Entry entry) { ... } private Uri GetUriImpl(EntryComment comment) { ... } 

    在这种情况下,如果它不是已知类型,您可能需要某种“逆止”方法。

  • 你可以创建一个Dictionary>

     private static Dictionary> UriProviders = new Dictionary> { { typeof(Entry), value => ... }, { typeof(EntryComment), value => ... }, { typeof(Blog), value => ... }, }; 

    然后:

     public Uri GetUri(object obj) { Func provider; if (!UriProviders.TryGetValue(obj.GetType(), out provider)) { // Handle unknown type case } return provider(obj); } 

    请注意,这包括您收到Entry等子类型的情况。

这些都不是特别好,请注意……我怀疑更高级别的重新设计可能更可取。

我认为Lasse V. Karlsen在他的评论中有权利,重新设计也许更合适

你可以像Stecya建议的那样创建一个界面

 public interface IUriAccessible { //or some sort of a more descriptive name Uri Url {get;} } 

然后对于你关心的每个对象,例如Entry ,你可以

 public class Entry:IUriAccessible { //... other code here public Uri Url { get { //return uri here } } } 

现在你可以在对象上调用它

 var entry = new Entry(); var uri = entry.Url; 

您可以使用要检查的所有类型的List()并迭代该列表。 但我认为这不会使代码更快。

你不能switch-case类型。

switch表达式或case标签必须是bool,char,string,integral,enum或相应的可空类型