我对C#中的通用类和继承有疑问。也许我在某个地方错了,并且这样的代码设计没有遵循最佳实践,但我真的希望能使它起作用。我具有以下类结构:
public class BaseInfo
{
public int Id { get; set; }
}
public class BaseData
{
}
public class SomeClass
{
public BaseData Data { get; protected set; }
public BaseInfo Info { get; protected set; }
}
public class SomeClass<TData, TInfo> : SomeClass
where TData : BaseData, new()
where TInfo : BaseInfo, new()
{
public new TData Data { get; protected set; }
public new TInfo Info { get; protected set; }
public SomeClass()
{
Data = new TData();
Info = new TInfo();
}
}
然后我指定了一个特定的类:
public class SpecificInfo : BaseInfo
{
public int MaxNumber { get; set; }
}
public class SpecificData : BaseData
{
public int StartFrom { get; set; }
}
public class SpecificClass : SomeClass<SpecificData, SpecificInfo>
{
public SpecificClass(int startFrom, int maxNumber)
{
Data = new SpecificData
{
StartFrom = startFrom
};
Info = new SpecificInfo
{
Id = 1,
MaxNumber = maxNumber
};
}
}
然后,我想在程序中使用它:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var specific = new SpecificClass(100, 1000);
Process(specific);
}
static void Process(SomeClass someClass)
{
var data = someClass.Data;
if (data is SpecificData specificData)
{
Console.WriteLine($"This is specific data {specificData.StartFrom}");
}
else
{
Console.WriteLine("This is not specific data, sorry");
}
}
}
但是它表明数据不是SpecificData
。我猜这是行不通的,因为SomeClass.Data
添加了new
关键字,所以对象中有两个Data
属性specific
。是否可以重写此代码以将非通用类Process(SomeClass someClass)
保存为方法的参数,并通过一些修改保存其余的类结构,但使其可行?也许我可以Data
在Process
方法内部找到所需的?谢谢!
通过使用接口而不是基类,并使用显式接口实现来实现接口的属性,可以解决此问题:
public interface ISomeClass
{
BaseData Data { get; }
BaseInfo Info { get; }
}
public class SomeClass<TData, TInfo> : ISomeClass
where TData : BaseData, new()
where TInfo : BaseInfo, new()
{
public TData Data { get; protected set; }
BaseData ISomeClass.Data => Data;
public TInfo Info { get; protected set; }
BaseInfo ISomeClass.Info => Info;
public SomeClass()
{
Data = new TData();
Info = new TInfo();
}
}
如果您使用的是C#9,则还可以使用返回类型的协方差:
public abstract class BaseClass
{
public abstract BaseData Data { get; }
public abstract BaseInfo Info { get; }
}
public class SomeClass<TData, TInfo> : BaseClass
where TData : BaseData, new()
where TInfo : BaseInfo, new()
{
public override TData Data { get; }
public override TInfo Info { get; }
public SomeClass()
{
Data = new TData();
Info = new TInfo();
}
}
请注意,我必须将属性设置SomeClass
为仅getter,因为基本属性必须为仅getter,并且您不能set
在覆盖中添加访问器。
如果确实需要在构造函数之外设置此属性,则可以执行以下操作:
public class SomeClass<TData, TInfo> : BaseClass
where TData : BaseData, new()
where TInfo : BaseInfo, new()
{
protected TData MutableData { get; set; }
public override TData Data => MutableData;
protected TInfo MutableInfo { get; set; }
public override TInfo Info => MutableInfo;
public SomeClass()
{
MutableData = new TData();
MutableInfo = new TInfo();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句