如何扩展C#类

时间:2012-02-20 15:54:29

标签: c# .net

我的代码类似于

IEnumerable<TwitterStatus> mentions = service.ListTweetsOnHomeTimeline();
RecentTweetList.ItemsSource = mentions;

我想要做的是以某种方式添加 TwitterStatus 1个额外属性来转换该类的 CreatedDate 以获得分钟。 (我无法重新设计TwitterStatus。)

所以我猜想这样做:

public class NewTwitterStatus : TwitterStatus
{
        public string MinAgo 
        {
            get 
            {
                TimeSpan diff = DateTime.Now.Subtract(base.CreatedDate);
                return diff.Minutes.ToString() + "m";
            }
        }
}

但我无法弄清楚如何进行演员表?

IEnumerable<NewTwitterStatus > mentions = (????)service.ListTweetsOnHomeTimeline();

谢谢你们所有人!

解决方案(基于Chris的建议):

IEnumerable<NewTwitterStatus> mentions = service.ListTweetsOnHomeTimeline().Select(x => new NewTwitterStatus(x));
RecentTweetList.ItemsSource = mentions;



 public class NewTwitterStatus
    {
        TwitterStatus Data { set; get; }

        public NewTwitterStatus(TwitterStatus ts)
        {
            Data = ts;
            ts = null;
        }

        public string ProfileImageUrl
        {
            get
            {
                return Data.User.ProfileImageUrl;
            }
        }


        public string ScreenName
        {
            get
            {
                return Data.User.ScreenName;
            }
        }

        public string UserName
        {
            get
            {
                return Data.User.Name;
            }
        }

        public string Text
        {
            get
            {                
                return Data.Text;
            }
        }

        public string MinAgo 
        {
            get 
            {
                TimeSpan diff = DateTime.Now.Subtract(Data.CreatedDate);
                int mins = diff.Minutes * -1;

                if (mins < 60)
                    return mins.ToString() + "m";
                else  
                {
                    double h = mins / 60;
                    double m = mins % 60;
                    return h.ToString()  + "h " + m.ToString() + "m";
                }


            }
        }

3 个答案:

答案 0 :(得分:9)

您不能以这种方式扩展类 - 您收到的TwitterStatus个实例根本没有您想要的属性。一种解决方法是使用扩展方法:

public static class TwitterExtensions
{
    public static string MinutesAgo(this TwitterStatus status)
    {
        TimeSpan diff = DateTime.Now.Subtract(status.CreatedDate);
        return diff.Minutes.ToString() + "m";
    }
}

现在,您可以在MinutesAgo()个实例上调用TwitterStatus方法:

foreach(var status in mentions)
{
   string howManyMinutesAgo = status.MinutesAgo();
}

修改

您应该能够使用扩展方法 - 另一种方法是使用AutoMapper之类的映射工具将TwitterStatus属性复制到扩展类 - 这将允许您在扩展方法上进行数据绑定使用自定义属性的类实例。这是很多额外的工作(计算上,通常不用于编码),所以如果你能够使用扩展方法,我不推荐它:

Mapper.CreateMap<TwitterStatus, NewTwitterStatus>();
IEnumerable<TwitterStatus> mentions = service.ListTweetsOnHomeTimeline();
IEnumerable<NewTwitterStatus> extendedMentions = mentions.Select(x=> Mapper.Map<NewTwitterStatus>(x));

答案 1 :(得分:7)

如果你不能做一个扩展方法,那么我会让你的NewTwitterStatus类有一个构造函数,它允许TwitterStatus允许轻松转换,然后使用一些linq,如下所示:

IEnumerable<NewTwitterStatus > mentions = 
    service.ListTweetsOnHomeTimeline().Select(x=> new NewTwitterStatus(x));

这将基本上采用原始的IEnumberable并将元素映射到新类型。它比扩展方法更优雅,但应该做到这一点。

答案 2 :(得分:5)

您不能将基类强制转换为子类。

您有多种选择(按推荐顺序)

  1. 扩展方法
  2. Decorator Pattern
  3. 部分课程
  4. 隐式转换
  5. 我真的推荐选项1,但我列出了其他两个用于学习的经历。


    Extension Method

    Extentension方法要求您在项目中创建一个静态公共类,然后从传入this DataType whateer的静态方法中,这将允许您在不修改类的情况下调用函数,这就是LINQ的工作方式。

    public static class ExtensionClasses
    {
        public static string MinAgo(this TwitterStatus status)
        {
            TimeSpan diff = DateTime.Now.Subtract(status.CreatedDate);
            return diff.Minutes.ToString() + "m";
        }
    }
    
    //Use
    {
        IEnumerable<TwitterStatus> mentions = service.ListTweetsOnHomeTimeline();
        foreach(var mention in mentions)
        {
            var minAgo = mention.MinAgo();
            //Do somthing with minAgo
        }
    }
    

    Partial Classes

    要使用部分类,请在类声明中使用关键字partial。您何时可以使用它有一些限制(在您的情况下可能无法实现)。有关详细信息,请参阅MSDN article

    public partial class TwitterStatus
    {
            public string MinAgo 
            {
                get 
                {
                    TimeSpan diff = DateTime.Now.Subtract(this.CreatedDate);
                    return diff.Minutes.ToString() + "m";
                }
            }
    }
    
    
    //Use
    {
        IEnumerable<TwitterStatus> mentions = service.ListTweetsOnHomeTimeline();
        foreach(var mention in mentions)
        {
            var minAgo = mention.MinAgo;
            //Do somthing with minAgo
        }
    }
    

    Implicit Conversion

    隐式转化是您在问题中未包含在原始示例中的步骤。

    //This code is untested and not gaunteed to work,
    public class NewTwitterStatus
    {
        private NewTwitterStatus(TwitterStatus twitterStatus)
        {
            this.twitterStatus = twitterStatus;
        }
    
        private TwitterStatus twitterStatus
    
        public string MinAgo 
        {
            get 
            {
                TimeSpan diff = DateTime.Now.Subtract(base.CreatedDate);
                return diff.Minutes.ToString() + "m";
            }
        }
    
        public static implicit operator NewTwitterStatus(TwitterStatus status)
        {
            return new NewTwitterStatus(status);
        }
    
        public static implicit operator TwitterStatus(NewTwitterStatus status)
        {
            return status.twitterStatus;
        }
    
        //You will need to do this for ever function/Member in TwitterStatus
        public bool SomeFuncFromTwitterStatus()
        {
            return this.twitterStatus.SomeFuncFromTwitterStatus();
        }
    }
    
    
    //Use
    {
        IEnumerable<NewTwitterStatus> mentions = service.ListTweetsOnHomeTimeline();
        foreach(var mention in mentions)
        {
            var minAgo = mention.MinAgo();
            //Do somthing with minAgo
        }
    }