2

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?

ElfsЯUs
  • 1,188
  • 4
  • 14
  • 34

1 Answers1

1

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);
svick
  • 236,525
  • 50
  • 385
  • 514
  • I see. However, then you get the entire path for the interface. So if IFoo is part of collection.Bar.Foo, then it will print out Collection.Bar.Foo.IFoo.this[int i]. Any way around this? – ElfsЯUs May 20 '13 at 20:28
  • @ElfsЯUs You can use `new CodeTypeReference(iface.Name)`. – svick May 20 '13 at 20:35
  • That will still result in the entire name path... but I suppose I can then edit it down. – ElfsЯUs May 20 '13 at 20:57