我一直在努力处理一段C#代码,尽管我找到了解决问题的方法,但这绝不是理想的方法(请参见下面的DoSomething_WorksButNotIdeal())。

我想做的是,而不是使用if,else语句(根据我要支持的类型,它可能会很大)只是具有通用类型转换,但我无法使其正常工作。我试图在DoSomething_HelpMe()方法中对此进行演示。

无论如何要实现这一目标?任何帮助是极大的赞赏。

public interface ITag
{
    string TagName { get; }
    Type Type { get; }
}

public interface ITag<T> : ITag
{
    T InMemValue { get; set; }
    T OnDiscValue { get; set; }
}


public class Tag<T> : ITag<T>
{
    public Tag(string tagName)
    {
        TagName = tagName;
    }

    public string TagName { get; private set; }
    public T InMemValue { get; set; }
    public T OnDiscValue { get; set; }
    public Type Type{ get{ return typeof(T);} }
}

public class MusicTrack
{
    public MusicTrack()
    {
        TrackTitle = new Tag<string>("TrackTitle");
        TrackNumber = new Tag<int>("TrackNumber");

        Tags = new Dictionary<string, ITag>();
        Tags.Add(TrackTitle.TagName, TrackTitle);
        Tags.Add(TrackNumber.TagName, TrackNumber);
    }

    public IDictionary<string,ITag> Tags;

    public ITag<string> TrackTitle { get; set; }
    public ITag<int> TrackNumber { get; set; }
}


public static class Main
{
    public static void DoSomething_WorksButNotIdeal()
    {
        MusicTrack track1 = new MusicTrack();
        MusicTrack track2 = new MusicTrack();

        // Set some values on the tracks

        foreach (ITag tag in track1.Tags.Values)
        {
            Type type = tag.Type;

            if (type == typeof(string))
            {
                ((ITag<string>) tag).InMemValue = ((ITag<string>)track2.Tags[tag.TagName]).OnDiscValue;
            }
            else if (type == typeof(int))
            {
                ((ITag<int>)tag).InMemValue = ((ITag<int>)track2.Tags[tag.TagName]).OnDiscValue;
            }
            else if (type == typeof(bool))
            {
                ((ITag<bool>)tag).InMemValue = ((ITag<bool>)track2.Tags[tag.TagName]).OnDiscValue;
            }
            // etc etc
            else
            {
                throw new Exception("Unsupported type.");
            }
        }
    }

    public static void DoSomething_HelpMe()
    {
        MusicTrack track1 = new MusicTrack();
        MusicTrack track2 = new MusicTrack();

        // Set some values on the tracks

        foreach (ITag tag in track1.Tags.Values)
        {
            Type type = tag.Type;

            // THIS OBVIOUSLY DOESN'T WORK BUT I'M JUST TRYING TO DEMONSTRATE WHAT
            // I'D IDEALLY LIKE TO ACHIEVE
            ((ITag<typeof(type)>)tag).InMemValue = ((ITag<typeof(type)>)track2.Tags[tag.TagName]).OnDiscValue;
        }
    }
}

最佳答案

您无法拥有的任何原因:

public interface ITag
{
    string TagName { get; }
    Type Type { get; }
    object InMemValue { get; set; }
    object OnDiscValue { get; set; }
}


并使用ITag<T>使其更具体?

public interface ITag<T> : ITag
{
    new T InMemValue { get; set; }
    new T OnDiscValue { get; set; }
}


然后,您的方法可以只使用ITag。您需要类似(int Tag<T>)的东西:

object ITag.InMemValue
{
    get { return InMemValue; }
    set { InMemValue = (T)value; }
}
object ITag.OnDiscValue
{
    get { return OnDiscValue; }
    set { OnDiscValue = (T)value; }
}




(编辑)

另一个选择是对非通用ITag的方法:

void CopyValueFrom(ITag tag);


(关于它复制到/从中复制的内容可能更具体)

您的具体实现(Tag<T>)必须假定ITag实际上是ITag<T>并进行强制转换:

public void CopyFromTag(ITag tag) {
    ITag<T> from = tag as ITag<T>;
    if(from==null) throw new ArgumentException("tag");
    this.TheFirstProperty = from.TheSecondProperty;
}

08-16 11:42