C# 如何向编译器保证泛型类型将具有特定属性?
我想对多个变量类型(本机和对象)使用特定的操作,因此我使用通用返回类型,如下所示C# 如何向编译器保证泛型类型将具有特定属性?,c#,generics,C#,Generics,我想对多个变量类型(本机和对象)使用特定的操作,因此我使用通用返回类型,如下所示 private Generic Field<Generic>(String field) { if (BagOfJunk.Properties.Contains(field)) return (Generic)BagOfJunk[field]; return default(Generic); } NumericType protoNumber = Field<NumericTy
private Generic Field<Generic>(String field)
{
if (BagOfJunk.Properties.Contains(field))
return (Generic)BagOfJunk[field];
return default(Generic);
}
NumericType protoNumber = Field<NumericType>("beep");
int number = protoNumber != null ? protoNumber.Value : -1;
DateType protoDate = Field<DateType>("boop");
DateTime date = protoDate != null ? protoDate.Value : null;
将该属性放在接口(或类)中,并使用通用约束“where”:
公共接口IMyInterface
{
公共对象值{get;set;}
}
公共类C,其中T:imy接口
您可以使用接口并对类型应用where约束来实现该接口,如下所示:
interface IHasPropertyValue<TValue> {
TValue Value { get; }
}
class MyType {
public TValue Method<T, TValue>(T obj) where T : IHasPropertyValue<TValue> {
return obj.Value;
}
}
接口IHasPropertyValue{
TValue值{get;}
}
类MyType{
公共价值法(T obj),其中T:IHasPropertyValue{
返回对象值;
}
}
编辑:修改上面的代码,使其更具体到下面询问的评论。以目前为止的答案为基础,您需要创建一个将由
GenericIn
实现的接口,该接口将保证它具有属性值
,并且该属性的类型为GenericOut
interface IHasValue<TOut>
{
TOut Value { get; }
}
private TOut Field<TIn, TOut>(string field) where TIn : IHasValue<TOut>
{
var input = Field<TIn>(field);
return input == null ? default(TOut) : input.Value;
}
接口IHAS值
{
TOut值{get;}
}
私有TOut字段(字符串字段),其中TIn:IHasValue
{
var输入=字段(字段);
返回input==null?默认值(TOut):input.Value;
}
您可以添加接口或抽象基类型吗?@JacobKrall是的,我可以。但就我看来,这并没有解决我的问题。属性的返回类型也需要是泛型的。属性类型是什么?它需要是GenericOut,但编译器无法识别它…将其设置为对象并将其转换为GenericOut您是否建议该属性为公共对象值{get;},然后我将所述对象的属性值转换为方法中需要的任何值?啊,我被接口ObjectWithValue{public object Value{get;}欺骗了没有编译。但那是因为属性上的修改器public!我的错。至于如何检查类型的有效性?你是建议把它作为关键词吗?还有更好的方法吗?你的建议可以编译,但当调用int n=Field(“beep”);我得到一个错误:ProtoNumber和ObjectWithValue之间没有隐式转换。建议?是的。现在好多了。然而,@zdradkodavev建议的演员阵容似乎要短一些。但是,接口上的泛型类型为+1。以前没用过。:)它会编译,但当我按如下方式添加实际调用时:int n=Field(“beep”);,我收到投诉说ProtoNumber和ObjectWithValue之间没有转换。你的ProtoNumber
,ProtoDate
等等。类必须实现一个合适的ObjectWithValue
,这样才能工作。哦,那是行不通的。我不是这些的所有者(不能要求他们添加公共接口)。而且未来可能会有更多。我想这是不可能的…:(
public interface IMyInterface
{
public object Value { get; set; }
}
public class C<T> where T:IMyInterface
interface IHasPropertyValue<TValue> {
TValue Value { get; }
}
class MyType {
public TValue Method<T, TValue>(T obj) where T : IHasPropertyValue<TValue> {
return obj.Value;
}
}
interface IHasValue<TOut>
{
TOut Value { get; }
}
private TOut Field<TIn, TOut>(string field) where TIn : IHasValue<TOut>
{
var input = Field<TIn>(field);
return input == null ? default(TOut) : input.Value;
}