如何在“可能”类型的对象之间切换?
可能重复:
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
请注意,这不包括您收到
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或相应的可空类型