C# 通用接口列表
如果我有一个带有几个实现类的通用接口,例如:C# 通用接口列表,c#,generics,interface,C#,Generics,Interface,如果我有一个带有几个实现类的通用接口,例如: public interface IDataElement<T> { int DataElement { get; set; } T Value { get; set; } } public class IntegerDataElement : IDataElement<int> { public int DataElement { get; set; } public int Value {
public interface IDataElement<T>
{
int DataElement { get; set; }
T Value { get; set; }
}
public class IntegerDataElement : IDataElement<int>
{
public int DataElement { get; set; }
public int Value { get; set; }
}
public class StringDataElement : IDataElement<String>
{
public int DataElement { get; set; }
public String Value { get; set; }
}
公共接口IDataElement
{
int数据元素{get;set;}
T值{get;set;}
}
公共类整型数据元素:IDataElement
{
公共int数据元素{get;set;}
公共int值{get;set;}
}
公共类StringDataElement:IDataElement
{
公共int数据元素{get;set;}
公共字符串值{get;set;}
}
可以传递不同类型的实现类的集合,而不必作为对象传递
似乎不可能将返回值定义为
public IDataElement<T>[] GetData()
public-IDataElement[]GetData()
或
public-IDataElement[]GetData()
有什么建议吗?您当然可以声明:
public IDataElement<T>[] GetData<T>()
这在你的特殊情况下有用吗
不清楚在不知道数据元素类型的情况下,您希望如何使用数据元素集合。。。如果上述内容对您没有帮助,也许您可以进一步说明您希望如何处理这些集合。不,您不能这样做-唯一的选择是使用非通用接口:
public interface IDataElement
{
int DataElement { get; set; }
}
public interface IDataElement<T> : IDataElement
{
T Value { get; set; }
}
public interface IDataElement
{
int DataElement { get; set; }
object Value { get; set; }
}
或者,创建包装器并将其传递给了解所需类型的方法:
public class DataElementBag
{
private IDictionary<Type, List<object>> _elements;
...
public void Add<T>(IDataElement<T> de)
{
Type t = typeof(T);
if(!this._elements.ContainsKey(t))
{
this._elements[t] = new List<object>();
}
this._elements[t].Add(de);
}
public void IEnumerable<IDataElement<T>> GetElementsByType<T>()
{
Type t = typeof(T);
return this._elements.ContainsKey(t)
? this._elements[t].Cast<IDataElement<T>>()
: Enumerable.Empty<T>();
}
}
公共类DataElementBag
{
私有索引元素;
...
公共无效添加(IDataElement de)
{
类型t=类型(t);
如果(!this._elements.ContainsKey(t))
{
此._元素[t]=新列表();
}
此._元素[t].添加(de);
}
public void IEnumerable GetElementsByType()
{
类型t=类型(t);
返回此。\u elements.ContainsKey(t)
?此._元素[t].Cast()
:Enumerable.Empty();
}
}
不确定这是否有助于您的用例,但您可以创建一个没有任何内容的基本/标记接口
public interface IDataElement {}
并让您的变体通用接口继承自该接口(如Jon Skeet所示)
公共接口IDataElement
因此,您可以创建这些“对象”的集合,并使用其反变、非变的通用接口(多丰满的嘴啊)
var collection=new List(){…}
我想,当你使用一个元素时,你可能需要有点明确,但对我来说,这就是C#Type safety的意义所在(C#非常明确!),并避免使用对象
IDataElement<MyType> value = List.First(x => DataElement == 12);
IDataElement value=List.First(x=>DataElement==12);
或者使用稍微皱眉的显式演员阵容
var element = (IDataElement<MyType>)List.First(x => DataElement == 12);
var-element=(IDataElement)列表。第一个(x=>DataElement==12);
我之所以搜索这个问题,是因为我有一个像TTYpe Get()
这样的通用方法,因为我有点搞砸了策略/访问者模式。我想通过使用泛型类型作为方法的参数,向我的提供者询问一件任意的事情
听起来可能有点奇怪,但实际上我可以利用依赖项注入来注入任意数量的IDataElement实现,这些实现知道如何根据提供程序自行配置它们。。。我想做的就是
var sqlConnection = tenantProvider.Get<SqlConnection>();
var storageTyep = tenantProvider<StorageProvider>();
var-sqlConnection=tenantProvider.Get();
var storageTyep=tenantProvider();
借助泛型、变量泛型接口和标记接口的强大功能。。它工作得很好。在使用者处强类型,完成泛型实现
public TSetting GetSetting<TSetting>() where TSetting : class
{
var sp = tenantSettingsDictionary[typeof(TSetting)];
return sp as TSetting;
}
public TSetting GetSetting(),其中TSetting:class
{
var sp=租户设置字典[类型(设置)];
将sp返回为TSetting;
}
我尝试了非泛型基类,但它丢失了值的细节property@benPearce:但无论如何,您都不能使用它,因为您不知道所涉及的类型。请尝试演示如何使用代码,然后我们可以给您提供更好的建议。最后,我使用object GetValue()和SetValue(object)方法访问了非通用的基本接口。这样工作far@JonSkeet,我在哪里可以找到结构不支持协方差的原因?有很好的理由,但现在还不能想出一个:(@Erti ChrisEelmaa:看到了吗
IDataElement<MyType> value = List.First(x => DataElement == 12);
var element = (IDataElement<MyType>)List.First(x => DataElement == 12);
var sqlConnection = tenantProvider.Get<SqlConnection>();
var storageTyep = tenantProvider<StorageProvider>();
public TSetting GetSetting<TSetting>() where TSetting : class
{
var sp = tenantSettingsDictionary[typeof(TSetting)];
return sp as TSetting;
}