Search code examples
c#genericspartial-classestype-parameter

Can I pass a type argument to a *.xaml.cs class?


I want to pass a type parameter to my *.xaml.cs file. The C# code will look like this:

public partial class Filter<T> : Window where T : IFilterableType
{
    private readonly IEnumerable<T> _rows;
    public Filter(IEnumerable<T> rows)
    {
        this._rows = rows;
    }
}

Since this is a partial class, and since Visual Studio generates the other part of the class, I am concerned that my type parameter <T> will get deleted when Visual Studio regenerates the other part of the partial class. So far in my testing, this hasn't happened, but I want to be sure.

Can I pass a type argument to a *.xaml.cs file like this?

If not, is there any other way for my *.xaml.cs class to have a private List of some generic type? I would try something like what's below, but that of course doesn't compile.

public partial class Filter : Window
{
    private IEnumerable<T> _rows;
    public Filter() { }

    public void LoadList(IEnumerable<T> rows) where T : IFilterableType
    {
        this._rows = rows;
    }
}

Solution

  • Here's another option. I've gotten this to work, but it sure is ugly code. I use a simple object variable to hold the generic list. I use methods with constrained type parameters to ensure that I'm using the IFilterableType interface. I also check types in my DisplayList method to be sure I'm using the correct implementation of IFilterableType.

    If I call this.DisplayList using FilterB instead of FilterA, I will get an exception. This is the best solution I can come up with.

    public partial class Filter : Window
    {
        public Filter()
        {
            List<FilterA> listA = new List<FilterA>();
            this.SetList<FilterA>(listA);
            this.DisplayList<FilterA>();
        }
    
        public interface IFilterableType { string Name { get; } }
        public class FilterA : IFilterableType { public string Name { get { return "A"; } } }
        public class FilterB : IFilterableType { public string Name { get { return "B"; } } }
    
    
        private object _myList;
        private Type _type;
    
        public void SetList<T>(List<T> list) where T : IFilterableType
        {
            this._myList = list;
            this._type = typeof(T);
        }
    
        public void DisplayList<T>() where T : IFilterableType
        {
            if (this._myList is List<T>)
                this.DataContext = (List<T>)this._myList;
            else
                throw new ArgumentException();
        }
    }