Question

I am trying to create an explicit interface declaration index property. So for example:

public interface IFoo
{
    int this[int i]
}

public abstract class Foo : IFoo
{
    int IFoo.this[int i]
}

I have written the following bit of code to do so (this works for normal index properties, but not for explicit interface declaration index properties):

var iface = typeof(IFoo);
var method = iface.GetMethod("Item"); // get the indexer

CodeMemberProperty memberIndexer = new CodeMemberProperty();

memberIndexer.Name = iface.Name + ".Item";

memberIndexer.Type = new CodeTypeReference(method.ReturnType.Name);
memberIndexer.HasSet = true;
memberIndexer.HasGet = true;

foreach (var param in method.GetParameters())
{
    memberIndexer.Parameters.Add(
        new CodeParameterDeclarationExpression(
        new CodeTypeReference(param.ParameterType), param.Name));
}

// Explicit interface declaration cannot have any modifiers
memberIndexer.Attributes = ~MemberAttributes.Private;

// add to both set/get to NotImplementedException
var exceptionStatement = new CodeThrowExceptionStatement(
    new CodeObjectCreateExpression(
        new CodeTypeReference(typeof(System.NotImplementedException)),
        new CodeExpression[] { }));
memberIndexer.GetStatements.Add(exceptionStatement);                  
memberIndexer.SetStatements.Add(exceptionStatement);

TargetClass.Members.Add(memberIndexer);

However, this generates the following code:

int IFoo.Item
{
    get
    {
        throw new System.NotImplementedException();
    }
    set
    {
        throw new System.NotImplementedException();
    }
}

Any thoughts on how to do this correctly?

Was it helpful?

Solution

You shouldn't do this by changing the Name. Instead, you should use the property that's meant exactly for this purpose: PrivateImplementationType:

memberIndexer.PrivateImplementationType = new CodeTypeReference(iface);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top