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