繁体   English   中英

如何扩展C#类

[英]How to extend C# class

我有类似的代码

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();

谢谢你们所有人!

解决方案(基于克里斯的建议):

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";
                }


            }
        }

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

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

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

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));

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

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

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

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

你有几个选择(按推荐顺序)

  1. 扩展方法
  2. 装饰图案
  3. 部分类
  4. 隐式转换

我真的推荐选项1,但我列出了其他两个学习经验。


扩展方法

扩展方法要求你在项目中创建一个静态公共类,然后在你传入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 您何时可以使用它有一些限制(在您的情况下可能无法实现)。 有关详细信息,请参阅MSDN文章

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
    }
}

隐式转换

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

//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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM