Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解因继承和接口实现而变得复杂的泛型方法_C#_Generics_Inheritance_Interface - Fatal编程技术网

C# 理解因继承和接口实现而变得复杂的泛型方法

C# 理解因继承和接口实现而变得复杂的泛型方法,c#,generics,inheritance,interface,C#,Generics,Inheritance,Interface,我有一个实现的基类数据源和一个通用接口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;}

我有一个实现的基类数据源和一个通用接口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; }
}
类数据源
{
数据源(日期时间dt){}
数据源(IData数据){}
数据源(IData数据,DateTime dt){}
}
公共接口IDataSource,其中TValue:IData
{
TValue数据项{get;set;}
字符串根文件夹{get;}
}
我的派生类(没有任何成员)

BestSource:DataSource,IDataSource{}
ConsistentSource:数据源,IDataSource{}
BackupSource:数据源,IDataSource{}
现在我正在尝试在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;
    }
公共静态IEnumerable GetAllData(此IData实体)
其中TSource:DataSource,IDataSource
其中TValue:IData
{
字符串folderName=$“{entity.Name}”;
//一种方法是让它工作(至少不显示编译时错误)
//是在基类数据源中创建一个使用
//如果else级联以返回适当的实例。。。
TSource dataSource=(TSource)新数据源(entity).GetSource(t);
//但这显然是一种不好的做法。
//我不想使用反射,只是想了解更多关于继承的知识,并解决它。
//我需要它的一个实例,这样我就可以访问rootfolder目录下的json文件,还可以反序列化json。
var returnData=Directory.EnumerateFiles(dataSource.RootFolder+folderName)
.选择(x=>
反序列化对象(File.ReadAllText(x));
返回数据;
}
一个早期有效的简单解决方案是只向它传递一个DataSource派生类的实例。但后来我试图看看如何让它从它实现的接口的类型param中找出派生类。 这是我第一次尝试使用泛型

编辑:好的,所以我可以通过在所有数据源子类中创建一个无参数构造函数来实现我想要的功能。我真的很想避免这种情况,因为这样做的代价是通过添加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 };
}
此外,我还将数据源定义为:

public class DataSource<TValue> : IDataSource<TValue> where TValue : IData
(非通用版本)您可以尝试以下表达式:

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 };
}
此外,我还将数据源定义为:

public class DataSource<TValue> : IDataSource<TValue> where TValue : IData

这看起来像C。您应该应用适当的语言标记。您能发布所有相关代码(包括成员)并确保其可编译吗?现在你的代码很难使用,因此这个问题很难回答。这看起来像C。您应该应用适当的语言标记。您能发布所有相关代码(包括成员)并确保其可编译吗?现在你的代码很难使用,因此这个问题很难回答。
public class BestSource : DataSource<BestData>
public static IEnumerable<BestData> GetAllData(this BestData entity)
{
    return entity.GetAllData(() => new BestSource(entity));
}
var receiver2 = data.GetAllData();