Создание универсального интерфейса для класса, когда универсальный тип зависит от того, откуда вызывается - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь создать общий интерфейс, который может быть реализован классом, который должен иметь возможность возвращать ЛИБО Список типов Class1 ИЛИ Class2. Я не смог заставить это работать, потому что мне нужно передать универсальный тип IRules, и если я передам ClassAbstract, я столкнусь с проблемой ниже (очень краткий общий пример того, с чем я действительно имею дело), ​​где одно из свойствэто только один из производных типов, а не базовый тип.

Я не уверен, как я могу заставить это работать так, как я хочу - в основном в этом разделе я могу проверить тип списка и затем указать, что делать, но проблема в том, что, потому что я передаюClassAbstract как общий параметр, который тоже не будет работать ... есть ли способ заставить это работать должным образом без указания типа интерфейса, потому что я на самом деле не знаю, будет ли это List of Class1 или ListClass2 и в зависимости от того, откуда он вызывается? Я, очевидно, мог бы продублировать код и просто использовать один раз метод для каждого типа класса, но это много кода, и я не думаю, что это должно быть так сложно сделать, что я хочу сделать, но, возможно, я ошибаюсь ...

public interface IRules<T> {
List<T>GetAdditionalPropRules(List<T> list1);
List<T>SetAdditionalPropRules(List<T> list1);
}

public ClassAbstract {
  public string NAME {get;set;}
  public string AGE {get;set;}
}

public class Class1: ClassAbstract {
  public string JOB {get;set;}
}

public class Class2: ClassAbstract {

}

public class Rules MyProperties: IRules<ClassAbstract>{ **<--- I Want this to be able to accept either Class1 or Class2**
  public List<ClassAbstract> SetAdditionalPropRules(List<ClassAbstract> myList) {
    foreach(dynamic item in myList) {
      if(item.NAME == "Joe") {
        myList.Add(new ClassAbstract {
          AGE = 30,
          JOB = "Tester" **<--- ISSUE RIGHT HERE -- ClassAbstract Does not have property JOB**
}
}
}
}
}

Ответы [ 2 ]

0 голосов
/ 08 октября 2019

Вам это поможет?

using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApp
{

  static partial class Program
  {

    static void Main(string[] args)
    {
      Test();
      Console.WriteLine();
      Console.WriteLine("End.");
      Console.ReadKey();
    }
    static void Test()
    {
      var rules = new RulesMyProperties();
      var list = new List<ClassAbstract>();
      list.Add(new Class1 { NAME = "Joe", AGE = 20 });
      list.Add(new Class2 { NAME = "Joe", AGE = 25 });
      list.Add(new Class1 { NAME = "John", AGE = 30 });
      list.Add(new Class2 { NAME = "John", AGE = 35 });
      Action print = () =>
      {
        foreach ( var item in list )
        {
          Console.Write($"{item.NAME} / {item.GetType().Name} : {item.AGE}");
          if ( item is Class1 )
            Console.Write($" ({((Class1)item).JOB})");
          Console.WriteLine();
        }
      };
      print();
      rules.SetAdditionalPropRules(list);
      Console.WriteLine();
      print();
    }
  }
  public class RulesMyProperties : IRules<ClassAbstract>
  {

    public List<ClassAbstract> SetAdditionalPropRules(List<ClassAbstract> myList)
    {
      foreach ( var item in myList.ToList() )
      {
        if ( item != null )
          if ( item.NAME == "Joe" )
          {
            if ( item is Class1 )
            {
              ( item as Class1 ).AGE = 30;
              ( item as Class1 ).JOB = "Tester";
            }
            else
            {
              myList.Remove(item);
              myList.Add(new Class1
              {
                NAME = "Joe",
                AGE = 30,
                JOB = "Tester"
              });
            }
            break;
          }
      }
      return myList;
    }

    public List<ClassAbstract> GetAdditionalPropRules(List<ClassAbstract> list1)
    {
      throw new NotImplementedException();
    }

  }
  public interface IRules<T>
  {
    List<T> GetAdditionalPropRules(List<T> list1);
    List<T> SetAdditionalPropRules(List<T> list1);
  }
  public class ClassAbstract
  {
    public string NAME { get; set; }
    public int AGE { get; set; }
  }
  public class Class1 : ClassAbstract
  {
    public string JOB { get; set; }
  }
  public class Class2 : ClassAbstract
  {

  }
}

Вывод:

Joe / Class1 : 20 ()
Joe / Class2 : 25
John / Class1 : 30 ()
John / Class2 : 35

Joe / Class1 : 30 (Tester)
Joe / Class2 : 25
John / Class1 : 30 ()
John / Class2 : 35
0 голосов
/ 08 октября 2019

возможно, вот так? - если вы основываете ваши Class1 и Class2 на каком-то интерфейсе:

     interface IClassAbsract
         {
             string Name { get; set; }
             string Age { get; set; }
         }
         public class Class1: IClassAbsract
         {
             public string Name { get; set; }
             public string Age { get; set; }
         }
         public class Class2 : IClassAbsract
         {
             public string Name { get; set; }
             public string Age { get; set; }
         }

         public class ListRule
         {
             public List<IClassAbsract> List { get; set; } = new List<IClassAbsract>();
         }

, то позже их можно использовать так:

            ...
     ...
     //populate list with testing instances
     var list = new ListRule();
     var c1 = new Class1() { Name = "Class #1", Age = "11" };
     list.List.Add(c1);

     var c2 = new Class2() { Name = "Class #2", Age = "22" };
     list.List.Add(c2);

     ...
     //then, get only certain types, and populate second list "myList": for example, pull only of type Class1:
     public  void Test2(List<IClassAbsract> list)
     {
             if (list == null || !list.Any())
             {
                     throw new System.ArgumentNullException("empty");
             }
             //pull only of type Class1:
             List<IClassAbsract> myList = new List<IClassAbsract>();
             myList.AddRange(list
                    .Where(e => e is Class1)
                     .Select(e => new Class1() { Age = e.Age, Name = "Joe" })
                     .ToList()
             );
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...