-2

I have following class:

public class ContentVideoType
{
    public string Title { get; set; }
    public string GetThumbnail { get; set; }
}

When creating an instance of this class, I want to assign a custom getter for GetThumbnail. I don't know how it is called but as far as I know the code must be like:

var youtube = new ContentVideoType
{
    Title = "Youtube",
    GetThumbnail = (x) => { return $"https://i.ytimg.com/vi/{x}/mqdefault.jpg"; }
};

var vimeo = new ContentVideoType
{
    Title = "Vimeo",
    GetThumbnail = (x) => GetVimeoImage(x)
};

For Viemo for example I need to call following function for GetThumbnail:

public static string GetVimeoImage(string vimeoId)
{
    string result = String.Empty;
    try
    {
        XmlDocument doc = new XmlDocument();
        doc.Load("http://vimeo.com/api/v2/video/" + vimeoId + ".xml");

        XmlElement root = doc.DocumentElement;
        result = root.FirstChild.SelectSingleNode("thumbnail_medium").ChildNodes[0].Value;
    }
    catch
    {
        //cat with cheese on it's face fail
    }

    return result;
}
HasanG
  • 12,734
  • 29
  • 100
  • 154
  • 1
    Your code should not even compile..... GetThumbnail = (x) => { return $"https://i.ytimg.com/vi/{x}/mqdefault.jpg"; }... also do you mean get by type/title? – dipak Jul 31 '17 at 16:13
  • It doesn't. That is the problem actually. I have the idea but I don't know how make it run. – HasanG Jul 31 '17 at 16:23

4 Answers4

2

It sounds like you want GetThumbnail to be a method that returns a string, not just a string. You can re-declare this way in order to do that:

public Func<string, string> GetThumbnail { get; set; }

That would cause this code to compile:

var youtube = new ContentVideoType
{
    Title = "Youtube",
    GetThumbnail = (x) => { 
        return string.Format("https://i.ytimg.com/vi/{0}/mqdefault.jpg", x); }
};

Note that the GetThumbnail above only accepts a method that takes one argument and returns a string.

Edit: Here's an example of how to use this:

string thumbnail = youtube.GetThumbnail("abc");
user2023861
  • 8,030
  • 9
  • 57
  • 86
2

I suppose, that you want to achieve inheritance in some odd way :) You should really use proper inheritance here (GetThumbnail should be method if it is receiving a string as a parameter):

public abstract class ContentVideoType
{
    public virtual string Title { get; set; }
    public virtual string GetThumbnail(string id)
    {
        return "Some Default Thumbnail";
    }
}

public class YouTubeContentVideType : ContentVideoType
{
    public override string GetThumbnail(string id)
    {
        return "";//your logic for youTube
    }
}

public class VimeoContentVideType : ContentVideoType
{
    public override string GetThumbnail(string id)
    {
        return "";//your logic for vimeo
    }
}

=== UPDATE ===

Basing on your latest response - here is how it would look :

        void Main()
        {           
            foreach (var videoType in GetAll)
            {
                Console.WriteLine(videoType.Title + " " + videoType.GetThumbnail("1")));
            }
        }

        public abstract class ContentVideoType
        {
            public virtual string Title { get; }
            public virtual string GetThumbnail(string id)
            {
                return "Some Default Thumbnail";
            }
        }

        public class YouTubeContentVideoType : ContentVideoType
        {
            public override string Title { get; } = "Youtube"; 

            public override string GetThumbnail(string id)
            {
                return $"https://i.ytimg.com/vi/{id}/mqdefault.jpg";
            }
        }

        public class VimeoContentVideType : ContentVideoType
        {
            public override string Title { get; } = "Vimeo";

            public override string GetThumbnail(string id)
            {
                return GetVimeoPreview(id);
            }

            public string GetVimeoPreview(string videoId)
            {
                return $"url:{videoId}"; //your code here;
            }
        }

        public static List<ContentVideoType> GetAll
        {
            get
            {
                var result = new List<ContentVideoType>
                {
                    new YouTubeContentVideoType(),
                    new VimeoContentVideType()
                };

                return result;
            }
        }
Piotr
  • 1,155
  • 12
  • 29
0

Could you create two sub-classes to ContentVideoType and each one implementing their own version of GetThumbnail?

Otherwise, the fact of being able to swap getters with reflection seems impossible: https://stackoverflow.com/a/6835824/2525304

Maxime
  • 2,192
  • 1
  • 18
  • 23
0

Ok, here is how I did it with a little help and guessing :)

public class ContentVideoType
{
    public string Title { get; set; }

    public Func<string, string> GetThumbnail { get; set; }
}

public static List<ContentVideoType> GetAll
{
    get
    {
        var result = new List<ContentVideoType> {
            new ContentVideoType
            {
                Title = "Youtube",
                GetThumbnail = videoId => $"https://i.ytimg.com/vi/{videoId}/mqdefault.jpg"
            },

            new ContentVideoType
            {
                Title = "Vimeo",
                GetThumbnail = videoId => GetVimeoPreview(videoId)
            }
        };

        return result;
    }
}
HasanG
  • 12,734
  • 29
  • 100
  • 154
  • 1
    It would theoretically work, but it is incorrect in terms of objective programming. You should use inheritance (as proposed by me) Objects behavior is known at compilation time - no need to "create" behaviors at runtime. If those methods would be declared in classes - you can still have exactly the same method as you posted - only, that it will use polymorphism as a mechanism – Piotr Jul 31 '17 at 17:11
  • 1
    Hasan - see my answer above (i've updated you to show you how it can be done) – Piotr Jul 31 '17 at 17:20