泛型方法和访问具体实例属性
本文关键字:实例 属性 访问 泛型方法 | 更新日期: 2023-09-27 18:34:26
我有这些类(只是一个例子(:
/* 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
属性,我如何访问它? - 有没有更好的方法来实现我的方法?
转换为抽象应该没有问题,您还可以添加接口定义并让您的类继承它们,例如:
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
因为数据。相关返回 InfoBase 的 IList,而不是 InfoBase 类本身。
编辑:
您必须更清楚地了解您希望从相关(或什么是获取参数列表(中获得什么。
编辑 2:
下面是适合您的添加方法代码:
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
}
}
编辑3:
这是工作代码:
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);
}
}
但。。。整个代码看起来不太好:)
有几个可能的改进:
- 您可以将 Add 方法移动到类 Data 中,然后重写
- 您可以将相关的 Id 传递到 add 方法中,而不是传递整个对象
- 您可以重新考虑域并检查是否真的需要如此多的重载。