C# 我可以为具有相同属性名称的两个类定义公共接口吗?
假设我有以下类层次结构:C# 我可以为具有相同属性名称的两个类定义公共接口吗?,c#,C#,假设我有以下类层次结构: class A { } class B : A { } class C : A { } 我有两个容器类: class BContainer { public B[] value { get; set; } } class CContainer { public C[] value { get; set; } } 我需要定义一个方法,该方法可以接受两个类实例中的任何一个,并且可以访问值属性,而无需诉诸反射。有没有一种方法可以定义两个类都可以实现的接口(比如说ICont
class A { }
class B : A { }
class C : A { }
我有两个容器类:
class BContainer { public B[] value { get; set; } }
class CContainer { public C[] value { get; set; } }
我需要定义一个方法,该方法可以接受两个类实例中的任何一个,并且可以访问值
属性,而无需诉诸反射。有没有一种方法可以定义两个类都可以实现的接口(比如说IContainer
?如果是这样,界面中的值
属性的类型是什么
用法示例:
void ProcessValue(IEnumerable<A> as) { ... }
void ExtractValue(IContainer container)
{
ProcessValue(container.value);
}
void ProcessValue(IEnumerable as){…}
无效提取值(IContainer容器)
{
ProcessValue(container.value);
}
您可以将接口定义为:
interface IContainer<T>
where T : A
{
T[] Value { get; set; }
}
接口IContainer
T:A在哪里
{
T[]值{get;set;}
}
那么你的课程应该是:
class BContainer : IContainer<B> { public B[] Value { get; set; } }
class CContainer : IContainer<C> { public C[] Value { get; set; } }
class BContainer:IContainer{public B[]Value{get;set;}
类CContainer:IContainer{public[]值{get;set;}
然后处理方法也应该是通用的:
void ExtractValue<T>(IContainer<T> container)
where T : A
{
ProcessValue(container.Value);
}
void提取值(IContainer容器)
T:A在哪里
{
ProcessValue(container.Value);
}
您可以将接口定义为:
interface IContainer<T>
where T : A
{
T[] Value { get; set; }
}
接口IContainer
T:A在哪里
{
T[]值{get;set;}
}
那么你的课程应该是:
class BContainer : IContainer<B> { public B[] Value { get; set; } }
class CContainer : IContainer<C> { public C[] Value { get; set; } }
class BContainer:IContainer{public B[]Value{get;set;}
类CContainer:IContainer{public[]值{get;set;}
然后处理方法也应该是通用的:
void ExtractValue<T>(IContainer<T> container)
where T : A
{
ProcessValue(container.Value);
}
void提取值(IContainer容器)
T:A在哪里
{
ProcessValue(container.Value);
}
似乎是泛型的好例子:
class Container<T> where T : A
{
public T[] value { get; set; }
}
类容器,其中T:A
{
公共T[]值{get;set;}
}
似乎是泛型的好例子:
class Container<T> where T : A
{
public T[] value { get; set; }
}
类容器,其中T:A
{
公共T[]值{get;set;}
}
由于两个类中的属性类型不同,因此该类型应该是两个属性的通用类型。在这种情况下,IEnumerable
应该可以。问题是,您定义的两个属性不能是此接口的实现,您可以使用显式接口实现来定义一个单独的属性,该属性与接口属性的实现同名
class A { }
class B : A { }
class C : A { }
interface IContainer
{
IEnumerable<A> value { get; }
}
class BContainer : IContainer
{
public B[] value { get; set; }
IEnumerable<A> IContainer.value => this.value;
}
class CContainer : IContainer
{
public C[] value { get; set; }
IEnumerable<A> IContainer.value => this.value;
}
class A{}
B类:A{}
C类:A{}
接口容器
{
IEnumerable值{get;}
}
B类容器:IContainer
{
公共B[]值{get;set;}
IEnumerable IContainer.value=>this.value;
}
类别C容器:I容器
{
公共C[]值{get;set;}
IEnumerable IContainer.value=>this.value;
}
用于显式实现的此属性将从类的外部和内部隐藏。如果访问
this.value
则访问的是value的类版本,除非引用显式转换为IContainer
(ex((IContainer)this.value)
这将访问属性的接口版本)由于两个类别中的属性类型不同,因此该类型应该是两个属性的通用类型。在这种情况下,IEnumerable
应该可以。问题是,您定义的两个属性不能是此接口的实现,您可以使用显式接口实现来定义一个单独的属性,该属性与接口属性的实现同名
class A { }
class B : A { }
class C : A { }
interface IContainer
{
IEnumerable<A> value { get; }
}
class BContainer : IContainer
{
public B[] value { get; set; }
IEnumerable<A> IContainer.value => this.value;
}
class CContainer : IContainer
{
public C[] value { get; set; }
IEnumerable<A> IContainer.value => this.value;
}
class A{}
B类:A{}
C类:A{}
接口容器
{
IEnumerable值{get;}
}
B类容器:IContainer
{
公共B[]值{get;set;}
IEnumerable IContainer.value=>this.value;
}
类别C容器:I容器
{
公共C[]值{get;set;}
IEnumerable IContainer.value=>this.value;
}
用于显式实现的此属性将从类的外部和内部隐藏。如果访问this.value
您正在访问value的类版本,除非引用被显式转换为IContainer
(ex((IContainer)this.value)
这将访问属性的接口版本)您可以执行以下操作:
public class A { }
public class B : A { }
public class C : A { }
public interface IContainer
{
A[] value { get; }
}
class BContainer : IContainer { public B[] value { get; set; } A[] IContainer.value { get { return this.value; } } }
class CContainer : IContainer { public C[] value { get; set; } A[] IContainer.value { get { return this.value; } } }
void ProcessValue(IEnumerable<A> arg) { }
void ExtractValue(IContainer container)
{
ProcessValue(container.value);
}
公共类A{}
公共B类:A{}
公共类C:A{}
公共接口IContainer
{
[]值{get;}
}
类BContainer:IContainer{public B[]value{get;set;}A[]IContainer.value{get{返回this.value;}}}
类CContainer:IContainer{public[]value{get;set;}A[]IContainer.value{get{返回this.value;}}}
void ProcessValue(IEnumerable arg){}
无效提取值(IContainer容器)
{
ProcessValue(container.value);
}
这至少可以编译。您可以这样做:
public class A { }
public class B : A { }
public class C : A { }
public interface IContainer
{
A[] value { get; }
}
class BContainer : IContainer { public B[] value { get; set; } A[] IContainer.value { get { return this.value; } } }
class CContainer : IContainer { public C[] value { get; set; } A[] IContainer.value { get { return this.value; } } }
void ProcessValue(IEnumerable<A> arg) { }
void ExtractValue(IContainer container)
{
ProcessValue(container.value);
}
公共类A{}
公共B类:A{}
公共类C:A{}
公共接口IContainer
{
[]值{get;}
}
类BContainer:IContainer{public B[]value{get;set;}A[]IContainer.value{get{返回this.value;}}}
类CContainer:IContainer{public[]value{get;set;}A[]IContainer.value{get{返回this.value;}}}
void ProcessValue(IEnumerable arg){}
无效提取值(IContainer容器)
{
ProcessValue(container.value);
}
这至少可以编译。如果您想要一个非通用的
IContainer
,可以将两个集合视为相同的集合,那么实际上没有一个非常干净的选项,因为类型不同。差异讨厌类型差异。当然,您可以使用泛型,但这会对您有所帮助,因为您需要分别检查每个封闭的泛型类型,就像您当前需要分别检查B
和C
一样
在非通用API上,最接近的方法是在IContainer
中返回Array
或IList
(非通用),这很可怕,不会让您前进太多
或者,如果您只需要枚举项目,则可以使用varian