Skip to content

WPF0072 raised on type hierarchy containing and interface #436

Open
@michaelmairegger

Description

@michaelmairegger

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

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