理解由于继承和接口实现而变得复杂的泛型方法
本文关键字:实现 接口 变得复杂 泛型方法 于继承 继承 | 更新日期: 2023-09-27 18:27:26
我有一个基类DataSource实现和一个通用接口IDataSource
class DataSource
{
DataSource (DateTime dt){}
DataSource (IData data) {}
DataSource (IData data, DateTime dt){}
}
public interface IDataSource<TValue> where TValue:IData
{
TValue DataEntry{get;set;}
string RootFolder { get; }
}
我的派生类(没有任何成员)
BestSource : DataSource, IDataSource<BestData> {}
ConsistentSource :DataSource, IDataSource<ConsistentData> {}
BackupSource : DataSource, IDataSource<BackupData> {}
现在我正试图在IData上创建一个扩展方法,它将创建适当的类并从中获取数据…
public static IEnumerable<TValue> GetAllData<TValue, TSource>(this IData entity)
where TSource : DataSource, IDataSource<TValue>
where TValue : IData
{
string folderName = $"_{entity.Name}";
//One way I kinda got it work (well atleast not show compiletime errors)
//was to create a method in base class DataSource that used
//if-else cascade to return an appropriate instance...
TSource dataSource = (TSource) new DataSource(entity).GetSource(t);
//but that's obviously a bad way of doing it.
//I want to avoid using reflection for no other reason than to just learn more about inheritence and working around/with it.
//I need an instance of it so I can access the json files at the rootfolder directory and also to deserilize the json.
var returnData = Directory.EnumerateFiles(dataSource.RootFolder+folderName)
.Select(x =>
JsonConvert.DeserializeObject<TValue>(File.ReadAllText(x)));
return returnData;
}
前面工作的一个简单解决方案是只向它传递DataSource派生类的一个实例。但后来我试着让它从它实现的接口的类型参数中找出派生类。这是我第一次尝试使用泛型。
编辑:好的,所以我能够通过在所有DataSource子类中创建一个无参数构造函数来实现我想要的。我真的很想避免这种情况,因为这是以通过添加setter使我的属性可变为代价的。呃,我只是从构造函数内部设置它们,效果很好。我将继续寻找一些方法来回到这一点,同时仍然保留扩展方法的功能。
(非通用版本)您可以尝试表达式:
public static IEnumerable<TValue> GetAllData<TValue>(this TValue entity, Func<DataSource<TValue>> func)
where TValue : IData
{
var obj = func();
// Get some data from obj, will be of type BestSource in this example
return new List<TValue>() { obj.DataEntry };
}
代码中的某个位置:
BestData data = new BestData();
var receiver = data.GetAllData(() => new BestSource(data));
此外,我确实将DataSource定义为:
public class DataSource<TValue> : IDataSource<TValue> where TValue : IData
最佳来源:
public class BestSource : DataSource<BestData>
同样为了编写更少的代码,您可以为每种数据类型定义扩展方法GetAllData:
public static IEnumerable<BestData> GetAllData(this BestData entity)
{
return entity.GetAllData(() => new BestSource(entity));
}
代码中的某个位置:
var receiver2 = data.GetAllData();