Skip to content

WPF0072 raised on type hierarchy containing and interface #436

Open
@michaelmairegger

Description

I have the following converter with the following types. Roslyn reports the following error:

WPF0072: ValueConversion must use correct types Expected: System.ComponentModel.IDataErrorInfo

[ValueConversion(typeof(BaseClass), typeof(string))]
public sealed class Test : IValueConverter
{
    public static readonly Test Default = new Test();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Sub1 a)
        {
            return string.Empty;
        }

        if (value is Sub2 rm)
        {
            return string.Empty;
        }

        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class BaseClass: IDataErrorInfo
{
    public string Error { get; } = "";

    public string this[string columnName] => throw new NotImplementedException();
}

public class Sub1 : BaseClass
{
}

public class Sub2 : BaseClass
{
}

This is wrong since not IDataErrorInfo should be allowed but BaseClass

Inspecting your code I found out, that

set.UnionWith(t1.RecursiveBaseTypes());
set.IntersectWith(t2.RecursiveBaseTypes());
return set.TryFirst(x => x is INamedTypeSymbol { IsGenericType: true }, out result) ||
set.TryFirst(out result);
returns the first common type which unfortunately is IDataError info; BaseClass comes second

Reproduction steps

Add the following test method to Valid.cs of WPF0072 tests, debug tests and set breakpoint to

return set.TryFirst(x => x is INamedTypeSymbol { IsGenericType: true }, out result) ||
and inspect the set variable.

    [Test]
    public static void Inheritance()
    {
        var code = @"
namespace Gu.Wpf.ToolTips.Demo.Wpf
{
    using System;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    using System.ComponentModel;

    public class BaseClass: IDataErrorInfo
    {
        public string Error { get; } = "";

        public string this[string columnName] => throw new NotImplementedException();
    }

    public class Sub1 : BaseClass
    {
    }

    public class Sub2 : BaseClass
    {
    }


    [ValueConversion(typeof(BaseClass), typeof(string))]
    public sealed class Test : IValueConverter
    {
        public static readonly Test Default = new Test();

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is Sub1 a)
            {
                return string.Empty;
            }

            if (value is Sub2 rm)
            {
                return string.Empty;
            }

            return string.Empty;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}";
        RoslynAssert.Valid(Analyzer, code);
    }

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions