0

I have two classes

[DataContract]
public class HiveReference : IGUID
{
    [BsonId]
    [DataMember]
    public Guid GUID{ get; set; }
    ....
}
...

[DataContract]
public class HiveByteChunk : IGUID
{
    [DataMember]
    [BsonId]
    public Guid GUID { get; set; }
    ...
}

My interface ...

public interface IGUID
{
    Guid GUID {get;set;}
}

Then I have an extension method ...

public static void InsertIfNotExists<T>(this T member) where T: IGUID
{
    if (!(member).Exists())
    {
        member.Insert();
    }
}

public static void Insert(this object member) 
{
    DBHelper.Insert(member);
}

Then my implementation code ...

HiveReference hf = new HiveReference();
hf.InsertIfNotExists();

HiveByteChunk chunk = new HiveByteChunk();
chunk.InsertIfNotExists();

The last line breaks, with this compiler error:

Error   CS0311
    The type 'HiveLibrary.HiveBytes.HiveByteChunk' cannot be used as type parameter 'T' in the generic type or method 'Extensions.InsertIfNotExists<T>(T)'.
    There is no implicit reference conversion from 'HiveLibrary.HiveBytes.HiveByteChunk' to 'HiveLibrary.IGUID'.

If both classes implements the interface, why would the first one be able to call the extension, but not the last? Am I missing something obvious?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
WynDiesel
  • 1,104
  • 7
  • 38
  • 1
    Well, actually this is not possible. You surely missed something which is also missing in your post. Can you try to generate a [mcve] (post the minimal but complete code to reproduce the problem). – René Vogt Dec 14 '17 at 13:36
  • Do both classes implement `HiveLibrary.IGUID`? – Wai Ha Lee Dec 14 '17 at 13:36
  • weird that the order of the [DataMember] [BsonId] would make a difference... do you have [DataContract] above both? (you have ... above the other, can't tell) – Kevin Cook Dec 14 '17 at 13:37
  • 1
    @KevinCook - the order of attributes doesn't matter - see [this](https://stackoverflow.com/q/2244163/1364007), for example. – Wai Ha Lee Dec 14 '17 at 13:38
  • @RenéVogt, not from this project, but I'll try recreating the scenario in a smaller project. – WynDiesel Dec 14 '17 at 13:39
  • @KevinCook, I've changed the order, no effect.And yes, sorry, ill edit the code, but both do implement DataContract – WynDiesel Dec 14 '17 at 13:39
  • @WaiHaLee, yes. both classes implement the interface – WynDiesel Dec 14 '17 at 13:40
  • What if you removed some of the 'chaff' (attributes on the two types and their properties, the body of `InsertIfNotExists`, and the `Insert` method)? – Wai Ha Lee Dec 14 '17 at 13:41
  • @WaiHaLee, I'm not sure I completely understand what you're saying. There are no attributes on the Insert and InsertIfNotExists methods, however, I removed the content from the method itself, without any change. – WynDiesel Dec 14 '17 at 13:44
  • I edited my comment - basically I wanted confirm that the attributes being present were unrelated to the problem. Likewise, the *contents* of `InsertIfNotExists` likely isn't relevant since it's a compiler error. In that case, the `Insert` method probably won't be relevant either. – Wai Ha Lee Dec 14 '17 at 13:46
  • 2
    Could it be that there is another `IGUID` in a different namespace and `HiveByteChunk` implements that? – Bill Tür stands with Ukraine Dec 14 '17 at 13:52
  • Thanks @ThomasSchremser , as I was busy butchering away code, I noticed exactly what you mentioned ... I had a duplicate IGUID interface hidden in the bottom of the class that I was testing with earlier, and forgot to remove. – WynDiesel Dec 14 '17 at 13:56
  • I cut and paste this set of classes and outside of not knowing what the member.exists() functionality was, the code compiled and I got into the extension method just fine. I see you got your answer above now... – Kevin Cook Dec 14 '17 at 13:58

1 Answers1

0

The problem was that I had a duplicate interface, in a different namespace. Once I removed that, everything worked as intended.

WynDiesel
  • 1,104
  • 7
  • 38