Alternative way of checking if an object is a matc

2019-06-24 04:36发布

if (this.Page is ArticlePage|| this.Page is ArticleListPage)
{
   //Do something fantastic
}

The above code works, but given the fact there could be many different classes I'd want to compare this.Page to, I would like to store the classes in a list and then perform a .Contains() on the list.

How would I achieve this? Would I use GetType() somehow? Could I store a list of Page objects and then compare the types somehow?

Note: You can assume all of the classes I'm comparing this.Page to extend Page.

3条回答
贪生不怕死
2楼-- · 2019-06-24 04:38

Hard to comment on your exact usage, but a (relatively) easy way to do this and add a bit more tidyness to your checks (especially if you perform the same checks in multiple places) is to define an interface, have the relevant pages implement that interface, then do the check against that.

The empty interface:

public interface IDoSomethingFantastic
{

}

So for example, your two page definitions might look like:

public partial class ArticlePage : System.Web.UI.Page, IDoSomethingFantastic
{

}

public partial class ArticleListPage : System.Web.UI.Page, IDoSomethingFantastic
{

}

Then your check is essentially:

if (this.Page is IDoSomethingFantastic)
{
    //Do something fantastic
}

This has the benefit of not having to centrally store a list of "fantastic" pages; instead you just define it on the page class declarations and it becomes easy to add/remove "fantastic" pages.

Additionally, you may be able to move your "fantastic" behaviour to the interface/page:

public interface IDoSomethingFantastic
{
    void SomethingFantastic();
}

Then in your checking code:

if (this.Page is IDoSomethingFantastic)
{
    ((IDoSomethingFantastic)this.Page).SomethingFantastic();
}

This way the implementation of something fantastic is handled elsewhere and not duplicated. Or you may move the checking and actions to a separate handling class altogether:

if (FantasticHandler.IsPageFantastic(this.Page))
    FantasticHandler.DoSomethingFantastic(this.Page);
查看更多
姐就是有狂的资本
3楼-- · 2019-06-24 04:44

This code will do the job:

HashSet<Type> knownTypes = new HashSet<Type>()
{
    typeof(ArticlePage),
    typeof(ArticleListPage),
    // ... etc.
};

if (knownTypes.Contains(this.Page.GetType())
{
   //Do something fantastic
}

EDIT: As pointed by Chris, you may want to consider type inheritance to fully mimic the behavior of is operator. That's a bit slower but can be more useful for some purposes:

Type[] knownTypes = new Type[] 
{ 
    typeof(ArticlePage), 
    typeof(ArticleListPage),
    // ... etc.
};

var pageType = this.Page.GetType();
if (knownTypes.Any(x => x.IsAssignableFrom(pageType)))
{
    //Do something fantastic
}
查看更多
相关推荐>>
4楼-- · 2019-06-24 04:53

Although you should double reconsider using such code (because it seems to forget about polymorphism), you can use Reflection to check it:

List<Type> types = new List<Type>() 
{ 
    typeof(ArticlePage), 
    typeof(ArticleListPage) 
};
types.Any(type => type.IsAssignableFrom(@object.GetType()));

IsAssignableFrom will be true not only for specific class but also for all its subclasses, exacly like is operator.

查看更多
登录 后发表回答