如何在对象的“可能”类型之间切换
本文关键字:类型 之间 可能 对象 | 更新日期: 2023-09-27 17:56:12
可能的重复项:
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 可以是的"可能"类型。
如何重构它?
谢谢。
几个选项:
-
如果使用的是 C# 4,则可以使用动态类型,并将该方法拆分为多个重载:
public Uri GetUri(dynamic obj) { return GetUriImpl(obj); } private Uri GetUriImpl(Entry entry) { ... } private Uri GetUriImpl(EntryComment comment) { ... }
在这种情况下,您可能需要某种"支持"方法,以防它不是已知类型。
-
您可以创建一个
Dictionary<Type, Func<object, Uri>>
:private static Dictionary<Type, Func<object, Uri>> UriProviders = new Dictionary<Type, Func<object, Uri>> { { typeof(Entry), value => ... }, { typeof(EntryComment), value => ... }, { typeof(Blog), value => ... }, };
然后:
public Uri GetUri(object obj) { Func<object, Uri> provider; if (!UriProviders.TryGetValue(obj.GetType(), out provider)) { // Handle unknown type case } return provider(obj); }
请注意,这不包括您收到子类型
Entry
等的情况。
请注意,这些都不是特别好...我怀疑更高级别的重新设计可能更可取。
你也可以用接口重构它
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
}
我认为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<Type>()
,并迭代该列表。 但我不认为这会让代码更快。
不能switch-case
类型。
开关表达式或大小写标签必须是布尔值、字符、字符串、积分、枚举或相应的可为空的类型