接口属性名称因类而异

时间:2011-02-11 12:13:42

标签: c# oop

这是问题所在。

public abstract class A {}
public class B:A 
{
    public TypeF FieldB;
}
public class C:A 
{
    public TypeG FieldC;
}
public class TypeF:A {  }
public class TypeG:A {  }

我想拥有接口ex:ITypeFG并在B和C BUT 中实现它以使属性名称为FieldB和FieldC

interface ITypeFG
{
    public A FieldFG;  //But i want to have names TypeF in A and TypeG in B
}

可以这样做吗? 感谢。

3 个答案:

答案 0 :(得分:5)

显式接口实现:

public class B : A, ITypeFG
{
    public TypeF FieldB { get; set; } // please don't expose public fields...
    A ITypeFG.FieldFG { get { return FieldB; } }
}
public class C : A, ITypeFG
{
    public TypeG FieldC { get; set; }
    A ITypeFG.FieldFG { get { return FieldC; } }
}

请注意,如果界面有setter,则需要强制转换:

public class B : A, ITypeFG
{
    public TypeF FieldB { get; set; }
    A ITypeFG.FieldFG { get { return FieldB; } set { FieldB = (TypeF)value; } }
}
public class C : A, ITypeFG
{
    public TypeG FieldC { get; set; }
    A ITypeFG.FieldFG { get { return FieldC; } set { FieldC = (TypeG)value; } }
}

答案 1 :(得分:3)

两点:

  1. C#中的接口不能包含字段,但它们可以具有属性。
  2. 所需的功能是不明智的:如果客户端总是必须知道实现的接口属性的“特定”名称以与实现进行交互,那么它的界面就不多了 - 它就更多了而不是标记。
  3. 正如Marc Gravell所说,一个不错的解决方法是使用显式实现。如果客户端具有对作为 interface 键入的实现对象的引用,则它们可以使用该属性的“常规”名称。如果他们有一个特定的引用(即键入为实现类型),他们可以使用“特定”名称(并且不会被通用名称混淆,因为他们不会在IntelliSense上看到它,例如)。

答案 2 :(得分:0)

听起来你应该将字段名称和A一起视为数据。这样你就可以保留一个通用的界面,只改变返回的内容:

class Data
{
    public string Name {get;set;}
    public A Value {get;set;}

}

interface ITypeFG
{
    Data Field {get;}
}

class B : A, ITypeFG
{
    public Data Field 
    {
        get
        {
            return new Data {Name = "TypeF", Value = FieldB};
        }
    }
}


class C : A, ITypeFG
{
    public Data Field 
    {
        get
        {
            return new Data {Name = "TypeG", Value = FieldC};
        }
    }
}