0

I used google translate

When I wrote the following code in C #, CS0453 occurred.

// This interface cannot be modified.
public interface InterfaceA {
    void Method ();
}

public struct StructA: InterfaceA {
    public void Method () {
        Console.WriteLine ("StructA");
    }
}

public struct StructB: InterfaceA {
    public void Method () {
        Console.WriteLine ("StructB");
    }
}

public class Wrapper {
    public InterfaceA abc;
}

public class InterfaceGenericTest {
    List <Wrapper> list;

    public void Main () {
        list = new List <Wrapper> ();
        list.Add (new Wrapper () {abc = new StructA ()});
        list.Add (new Wrapper () {abc = new StructA ()});
        list.Add (new Wrapper () {abc = new StructB ()});

        foreach (var item in list) {
            CallMethod <InterfaceA> (item.abc); // CS0453
        }
    }

    // This function cannot be modified.
    public void CallMethod <T> (T t)
        where T: struct, InterfaceA {
        t.Method ();
    }
}

Details of the error Error CS0453: The type'InterfaceA' must be a non-nullable value type in order to use it as parameter'T' in the generic type or method'InterfaceGenericTest.CallMethod (T)' (CS0453)

Therefore, I did a null check so that the CallMethod argument would not be null, but CS0453 occurred.

foreach (var item in list) {
    if (item.abc! = null) {
        CallMethod <InterfaceA> (item.abc); // CS0453
    }
}

I wondered if the compiler didn't realize it wasn't null, so I tried using the null conditional operator, but CS0453 occurred.

foreach (var item in list) {
    if (item.abc! = null) {
 // Made CallMethod an extension method.
        item.abc?. CallMethod <InterfaceA> (); // CS0453
    }
}

So when I set the class that implements InterfaceA as the argument of CallMethod, CS0453 occurred.

public class ClassA: InterfaceA {
    public void Method () {
        Console.WriteLine (“ClassA”);
    }
}

CallMethod <ClassA> (new ClassA ()); // CS0453

From this, I thought that the error could have occurred because the interface could be implemented in both the class and the struct, which could pass the class as an argument to CallMethod.

If the reason for the error is correct, how do I write the above code?

couyit
  • 1
  • 2
    Is there any reason your constraint is `where T: struct, InterfaceA` and not just `where T: InterfaceA`? ie/ why does it need to be constrained to a `struct`? – Jamiec Aug 10 '22 at 11:29
  • 1
    Without that constraint, your code works as expected: https://dotnetfiddle.net/EsYPtS – Jamiec Aug 10 '22 at 11:31
  • I think this is what you're looking for - but its not possible without changing that method you say cant be changed: https://stackoverflow.com/questions/42999660/constrain-interface-implementations-to-structs – Jamiec Aug 10 '22 at 11:36
  • I used google translate. Thank you for your comment. CallMethod is actually Unity's IJobParallelForExtensions.Schedule function. This function constrains the type parameter to struct. It cannot be changed. – couyit Aug 10 '22 at 11:44
  • Can't you fix this problem by changing something other than CallMethod? No class implements InterfaceA in my project. – couyit Aug 10 '22 at 11:59
  • No, for the reasons specified in the linked question above – Jamiec Aug 10 '22 at 13:28

0 Answers0