Наследование DataAnnotations через интерфейсC#

Место общения программистов C#
Anonymous
Наследование DataAnnotations через интерфейс

Сообщение Anonymous »

У меня есть два класса-близнеца, представляющие «одни и те же» объекты: один определен для вычислительных вычислений, а другой — для привязки пользовательского интерфейса. Я хотел бы уменьшить дублированный код и ошибки. Я определил общий интерфейс и переместил все общие статические методы, используя методы расширения.
Не хватает того, как определить проверку свойств в одном месте .
Сейчас я использую System.ComponentModel.DataAnnotations, но мне нужно определить одни и те же аннотации для обоих классов. В базовом классе я использую DataAnnotation для проверки десериализации JSON, в то время как в пользовательском интерфейсе используются те же значения.
Я не могу использовать наследование, поскольку класс пользовательского интерфейса уже наследуется от класса ViewModel, а множественное наследование не поддерживается. разрешено.
Есть ли другой подход или идея?
Здесь проект с той же основной концепцией.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;

namespace myRefactoring
{
public interface IShape
{
// would be nice to define the DataAnnotation here
// but it's not working with interfaces

public int N { get; set; }
public double side { get; set; }

public double perimeter { get; }
public double area { get; }
}

public class Shape : IShape
{
///
/// main class for math evaluations
///

[Range(3, int.MaxValue, ErrorMessage = "at least 3 sides")]
public int N { get; set; }

[Range(double.Epsilon, double.MaxValue, ErrorMessage = "just positive size")]
public double side { get; set; }

public Shape(int N, double S) { this.N = N; this.side = S; }

public double perimeter => ShapeExtension.perimeter(this);
public double area => ShapeExtension.area(this);

}

public class ShapeUI : ViewModel, IShape, INotifyPropertyChanged
{
///
/// class for UI binding
/// NotifyPropertyChanged ...
///

public event PropertyChangedEventHandler? PropertyChanged;

public ShapeUI(int N, double S) { this._N = N; this._side = S; }

private int _N;

[Range(3, int.MaxValue, ErrorMessage = "at least 3 sides")]
public int N {
get => _N;
set {
_N = value;
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(perimeter));
NotifyPropertyChanged(nameof(area));
}
}

private double _side;

[Range(double.Epsilon, double.MaxValue, ErrorMessage = "just positive size")]
public double side {
get => _side;
set {
if (value != this._side)
{
this._side = value;
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(perimeter));
NotifyPropertyChanged(nameof(area));
}
}
}

public double perimeter => ShapeExtension.perimeter(this);
public double area => ShapeExtension.area(this);

private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Console.WriteLine("changing " + propertyName);
}

}

public static class ShapeExtension
{
public static double perimeter(this IShape s) => s.N * s.side;
public static double area(this IShape s) => Math.Pow(s.side / 2, 2) / Math.Tan(Math.PI / s.N) * s.N;
}

public class ViewModel
{
// class implementing ViewModel methods and variables
}

internal class Program
{
static void Main(string[] ars)
{
Console.WriteLine("Create triangle");
Shape triangle = new(3, 1.0);
Console.WriteLine($"area = {triangle.area:F3}");

Console.WriteLine("\n\nCreate square");
ShapeUI square = new(4, 1.0);
Console.WriteLine($"area = {square.area:F3}");

Console.WriteLine("\n\nModify square");
square.side = 2.0;
Console.WriteLine($"area = {square.area:F3}");
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/787 ... -interface

Вернуться в «C#»