All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.csharp.S3444.html Maven / Gradle / Ivy

There is a newer version: 10.2.0.105762
Show newest version

Why is this an issue?

When an interface inherits from two interfaces that both define a member with the same name, trying to access that member through the derived interface will result in the compiler error CS0229 Ambiguity between 'IBase1.SomeProperty' and 'IBase2.SomeProperty'.

So instead, every caller will be forced to cast instances of the derived interface to one or the other of its base interfaces to resolve the ambiguity and be able to access the member. Instead, it is better to resolve the ambiguity in the definition of the derived interface either by:

  • renaming the member in one of the base interfaces to remove the collision
  • also defining that member in the derived interface. Use this only if all copies of the member are meant to hold the same value.

Noncompliant code example

public interface IBase1
{
  string SomeProperty { get; set; }
}

public interface IBase2
{
  string SomeProperty { get; set; }
}

public interface IDerived : IBase1, IBase2 // Noncompliant, accessing IDerived.SomeProperty is ambiguous
{
}

public class MyClass : IDerived
{
  // Implements both IBase1.SomeProperty and IBase2.SomeProperty
  public string SomeProperty { get; set; } = "Hello";

  public static void Main()
  {
    MyClass myClass = new MyClass();
    Console.WriteLine(myClass.SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase1)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase2)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IDerived)myClass).SomeProperty); // Error CS0229 Ambiguity between 'IBase1.SomeProperty' and 'IBase2.SomeProperty'
  }
}

Compliant solution

public interface IDerived : IBase1, IBase2
{
  new string SomeProperty { get; set; }
}

public class MyClass : IDerived
{
  // Implements IBase1.SomeProperty, IBase2.SomeProperty and IDerived.SomeProperty
  public string SomeProperty { get; set; } = "Hello";

  public static void Main()
  {
    MyClass myClass = new MyClass();
    Console.WriteLine(myClass.SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase1)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase2)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IDerived)myClass).SomeProperty); // Writes "Hello" as expected
  }
}

or

public interface IBase1
{
  string SomePropertyOne { get; set; }
}

public interface IBase2
{
  string SomePropertyTwo { get; set; }
}

public interface IDerived : IBase1, IBase2
{
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy