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

本文关键字:类型 之间 可能 对象 | 更新日期: 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类型。

开关表达式或大小写标签必须是布尔值、字符、字符串、积分、枚举或相应的可为空的类型