Here`s the question.
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 { }
I want to have interface ex: ITypeFG and to impl开发者_StackOverflowement it in B and C BUT to have properties names FieldB and FieldC
interface ITypeFG
{
public A FieldFG; //But i want to have names TypeF in A and TypeG in B
}
Can this be done? Thanks.
explicit interface implementation:
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; } }
}
Note that if the interface has a setter, you'll need to cast:
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; } }
}
Two points:
- Interfaces in C# can't have fields, but they can have properties.
- The desired feature isn't sensible: if clients would always have to know the "specific" name of the implemented interface-property to interact with an implementation, then it isn't much of an interface is it - it's little more than a marker.
As Marc Gravell suggests, a decent workaround is to use explicit implementations. If the client has a reference to the implementing object typed as the interface, they can use the "general" name of the property. If they have a specific reference (i.e. typed as the implementing type) , they can use the "specific" name (and won't be confused by the general name since they won't see it on IntelliSense, for example).
Sounds like you should treat the field names as data along with A. That way you can keep a common interface and only vary the content of what is returned:
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};
}
}
}
精彩评论