我一直在努力处理一段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;
}