我有这些课程(只是一个例子):
/* Data classes */
public class Data
{
public int Id { get; set; }
...
}
public InfoData<TInfo> : Data
where TInfo: InfoBase
{
public TInfo Info { get; set; }
...
}
/* Info classes */
// ABSTRACT
public abstract class InfoBase
{
public int Id { get; set; }
...
}
public class ExtraInfo : InfoBase
{
public IList<InfoBase> Related { get; set; }
}
// + other InfoBase inherited types
然后我有一个消耗Data
(或任何继承的类型实例)的方法,但必须读取作为参数传递的实际对象实例的其他属性:
TData Add<TData>(TData data)
where TData: Data
{
TData result = Get(
data.Id,
...
// how do I get to this one?
data.Related[0].Id
);
}
我可以访问所有Data
类属性,但是如何获得实际实例的其他属性,因为我不能仅仅转换为
data as InfoData<InfoBase>
因为InfoBase
是抽象的,我也不能用一些继承的非抽象类型来改变抽象泛型,因为会有太多的东西要考虑......
Related
属性?答案 0 :(得分:0)
在转换为abstract时应该没有问题,你也可以添加接口定义并让你的类继承它们,例如:
public interface IRelated{
IList<InfoBase>Related {get; set;}
}
public class ExtraInfo : InfoBase, IRelated
{
public IList<InfoBase> Related { get; set; }
}
public class OtherInfo:IRelated{
public IList<InfoBase> Related { get; set; }
}
并转换为接口而不是类:
ExtraInfo i = new ExtraInfo(){ Id = 5 };
var p = (InfoBase)i;
var q = (IRelated)i;
q.Related.Add(new ExtraInfo());
但是我可以在你的代码中看到其他问题:在Add方法中你输错了属性:
data.Related.Id
因为data.Related返回InfoBase的IList而不是InfoBase类本身。
你必须更清楚你期望从相关(或什么是获取参数列表)获得什么。
这里是您的添加方法代码:
TData Add<TData>(TData data) where TData:Data
{
var infoBase = data as InfoBase; //or IRelated as in my earlier samples
TData result;
if (infoBase != null)
{
result = Get(data.id, infoBase.Related[0].Id); //you can also use infoBase.Id as first param
}
else
{
result = Get(data.id, null); //whatever you need to pass to the method if there is no related item
}
}
这里的工作代码:
public class Data
{
public int Id { get; set; }
//...
}
public class InfoData<TInfo> : Data
where TInfo: InfoBase
{
public TInfo Info { get; set; }
//...
}
/* Info classes */
// ABSTRACT
public abstract class InfoBase
{
public int Id { get; set; }
// ...
}
public interface IRelated
{
IList<InfoBase> Related {get; set;}
}
public class ExtraInfo : InfoBase, IRelated
{
public IList<InfoBase> Related { get; set; }
}
public class OtherInfo : InfoBase, IRelated
{
public IList<InfoBase> Related { get; set; }
}
...
class MainClass
{
public static TData Get<TData>(int id, int? related)
where TData: Data
{
Console.WriteLine("id: {0}, related:{1}", id, related);
return (TData)null;
}
public static TData Add<TData>(TData data)
where TData: Data
{
return Get<TData>(data.Id,null);
}
public static TData Add<TData, TInfo>(TData data)
where TData: InfoData<TInfo>
where TInfo: InfoBase
{
var infoBase = data.Info as IRelated;
if (infoBase == null)
return Get<TData>(data.Id, null);
return Get<TData>(data.Id, infoBase.Related[0].Id);
}
public static void Main(string[] args) {
var i = new ExtraInfo {
Id = 5,
Related = new List<InfoBase> { new ExtraInfo { Id = 1 }}
};
var data = new InfoData<ExtraInfo> { Id = 100, Info = i };
var result1 = Add<InfoData<ExtraInfo>, ExtraInfo>(data);
var result2 = Add(data);
}
}
但......整个代码看起来不太好:))
有几种可能的改进: