Search code examples
xamlxamarinobsolete

*.xaml.g.cs file is showing an obsolete warning (CS0618). How to use Obsolete attribute in a partial class?


I have a custom view marked as obsolete with

[Obsolete("AccordionButton is deprecated, please use HeaderButton instead.")]

by adding this attribute to the *.xaml.cs file. Now I'm getting a warning in the xaml.g.cs file on compilation, because it is a partial class (consisting of *.xaml and *.xaml.cs code behind file).

I don't understand why I'm getting the warning, the view isn't used anywhere else. Yes, I could delete the file, but out of curiosity why doesn't he check that this is a partial class? How can I get rid of the warning and keeping the Obsolete attribute at the same time?

Edit:

Here is the 'full' code:

AccordionButton.xaml.cs

using MyProject.Common.CustomRenderers;
using System;
using Xamarin.Forms;

namespace MyProject.Views
{
#pragma warning disable 618
    [Obsolete("AccordionButton is deprecated, please use HeaderButton instead.")]
    public partial class AccordionButton : MultiLineButton
    {
        private bool expand = false;

        public bool Expand
        { 
            get{ return this.expand;}
            set{ this.expand = value;}
        }

        public ContentView AssociatedContent { get; set; }

        public AccordionButton()
        {

        }
    }
#pragma warning restore 618
}

AccordionButton.xaml

<?xml version="1.0" encoding="utf-8" ?>
<customViews:MultiLineButton xmlns="http://xamarin.com/schemas/2014/forms"
                         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                         x:Class="MyProject.Views.AccordionButton"
                         xmlns:customViews="clr-namespace:MyProject.Views;assembly=MyProject">

</customViews:MultiLineButton>

AccordionButton.xaml.g.cs

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: global::Xamarin.Forms.Xaml.XamlResourceIdAttribute("MyProject.Views.AccordionButton.xaml", "Views/AccordionButton.xaml", typeof(global::MyProject.Views.AccordionButton))]

namespace MyProject.Views {


    [global::Xamarin.Forms.Xaml.XamlFilePathAttribute("Views\\AccordionButton.xaml")]
    public partial class AccordionButton : global::MyProject.Views.MultiLineButton {

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
        private void InitializeComponent() {
            global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(AccordionButton));
        }
    }
}

If I double click the warning he marks this part global::MyProject.Views.AccordionButton. The warning only appears after compiling ...

When I compare this to a test project (where everything is working fine) the AccordionButton.xaml.g.cs looks like this

[assembly: global::Xamarin.Forms.Xaml.XamlResourceIdAttribute("TestObsolete.Views.AccordionButton.xaml", "Views/AccordionButton.xaml", null)]

So there is something in my project which is different, but I haven't figured out what and why.


Solution

  • The Obsolete attribute marks a program entity as one that is no longer recommended for use. Each use of an entity marked obsolete will subsequently generate a warning or an error, depending on how the attribute is configured.

    1.Set the obsolete on class

    [Obsolete("AccordionButton is deprecated, please use HeaderButton instead.")]
    public partial class Page1 : ContentView
    {
        public Page1()
        {
            InitializeComponent();
    
            Page2 page2 = new Page2();
            page2.method();
        }
    }
    

    enter image description here

    2.Set obsolete on method.

    [Obsolete("AccordionButton is deprecated, please use HeaderButton instead.")]
    public partial class Page1 : ContentView
    {
        public Page1()
        {
            InitializeComponent();
    
            Page2 page2 = new Page2();
            page2.method();
        }
    }
    public partial class Page2
    {
        [Obsolete("AccordionButton is deprecated, please use HeaderButton instead.",true)]
        public void method()
        {
            Console.Write("a");
        }
    }
    

    Set obsolete with IsError property. IsError is a Boolean value that indicates to the compiler whether using the ObsoleteAttribute attribute should cause it to emit an error (IsError is true) or a warning (IsError is false).

    enter image description here

    If you want to use Obsolete without warning, you could try the following ways.

    1.Ignore error in file

    `#pragma warning disable 618`
    
            Page2 page2 = new Page2();
            page2.method1();
    

    2.Ignore error in project

    enter image description here For more information about disable the warning, you could check the link. https://stackoverflow.com/a/40525222/11850033

    Updated:

    Thank you for your response! You have written a nice summary here. I tried to use #pragma warning disable and #pragma warning restore, but where should I put it to not get the warning? I'll edit my question so that you can have a look. What I still don't get is why this error occurs. The Xaml is using the partial class (so it is using itself) and this is enough to cause the warning?

    #pragma warning can enable or disable certain warnings.

    Usage:

    #pragma warning disable warning-list
    #pragma warning restore warning-list

    warning-list: A comma-separated list of warning numbers. The "CS" prefix is optional.

    When no warning numbers are specified, disable disables all warnings and restore enables all warnings.

    According to your code, you could put it before you used the obsolete class like below.

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            #pragma warning disable
            AccordionButton accordionButton = new AccordionButton();
            var s = accordionButton.Expand;
        }
    }
    

    To be clear: the warning should be thrown, when another View is using this component (AccordionButton). It should not be shown if the xaml and the code behind file are "working together".

    When the other view use this class, the error would be thrown as well.

    enter image description here