C# 跨多个类型(.Net)设计一个属性的最佳方法

C# 跨多个类型(.Net)设计一个属性的最佳方法,c#,.net,C#,.net,我有需求引导我走这条路 public interface IThing { string Id { get; set; } } public class ThingA : IThing { public string Id { get; set; } public string Value { get; set; } } public class ThingB : IThing { public string Id { get; set; } public

我有需求引导我走这条路

public interface IThing
{
    string Id { get; set; }
}
public class ThingA : IThing
{
    public string Id { get; set; }
    public string Value { get; set; }
}
public class ThingB : IThing
{
    public string Id { get; set; }
    public long Value { get; set; }
}
public class ThingC : IThing
{
    public string Id { get; set; }
    public bool Value { get; set; }
}

挑战在于用一个可以是string/long/bool的值来建模。我发现这是很难工作,因为不断的铸造检查,接口本身是没有用处的。我不知道有没有一种传统的方法来解决这个问题?还是有人发现的一种行之有效的模式?提前谢谢。

听起来你想要仿制药:

public interface IThing
{
   string Id { get; set; }
}
public class Thing<T> : IThing
{
  public string Id { get; set; }
  public T Value { get; set; }
}

public class Program
{
    public static void Main()
    {
      var thingA = new Thing<int>();
      var thingB = new Thing<string>();
    
      thingA.Id = "A";
      thingA.Value = 42;
    
      thingB.Id = "B";
      thingB.Value = "Is a B";
    
      Console.WriteLine(thingA.Value);
      Console.WriteLine(thingB.Value);
   }
}
public接口信息
{
字符串Id{get;set;}
}
公共类的东西:我喜欢
{
公共字符串Id{get;set;}
公共T值{get;set;}
}
公共课程
{
公共静态void Main()
{
var thingA=新事物();
var thingB=新事物();
thingA.Id=“A”;
厚度值=42;
thingB.Id=“B”;
thingB.Value=“是a B”;
控制台写入线(thingA.Value);
控制台写入线(thingB.Value);
}
}

其中您将有一个基类,该基类继承自您的接口,具有您想要的值类型。

听起来您想要泛型:

public interface IThing
{
   string Id { get; set; }
}
public class Thing<T> : IThing
{
  public string Id { get; set; }
  public T Value { get; set; }
}

public class Program
{
    public static void Main()
    {
      var thingA = new Thing<int>();
      var thingB = new Thing<string>();
    
      thingA.Id = "A";
      thingA.Value = 42;
    
      thingB.Id = "B";
      thingB.Value = "Is a B";
    
      Console.WriteLine(thingA.Value);
      Console.WriteLine(thingB.Value);
   }
}
public接口信息
{
字符串Id{get;set;}
}
公共类的东西:我喜欢
{
公共字符串Id{get;set;}
公共T值{get;set;}
}
公共课程
{
公共静态void Main()
{
var thingA=新事物();
var thingB=新事物();
thingA.Id=“A”;
厚度值=42;
thingB.Id=“B”;
thingB.Value=“是a B”;
控制台写入线(thingA.Value);
控制台写入线(thingB.Value);
}
}

在这里,您将拥有一个基类,它继承自您的接口,具有您想要的值类型。

我最终得到了这个设计。。。在知道值类型之前,我需要有一些可以实例化的基础。我无法通过使用泛型来避免这种方法的麻烦(大量的铸造),并且也阻止了我拥有不可知论的基础。如果可能的话,我想看看如何在这个场景中提高界面的可用性

public class BaseThing
{
    public string Id { get; set; }        
    public IValueConfig Configuration { get; set; }
    public string CommonProp { get; set; }...
}

public interface IValueConfig
{
    ValueType Type { get; }
}

public class RangeVal : IValueConfig
{
    public ValueType Type => ValueType.Range;
    public double Value { get; set; }
    public string UniqueProp { get; set; }...
}

public class StateVal : IValueConfig
{
    public ValueType Type => ValueType.State;
    public string Value { get; set; }
    public string UniqueProp { get; set; }...
}

public class BooleanVal : IValueConfig
{
    public ValueType Type => ValueType.Boolean;
    public bool Value { get; set; }
    public string UniqueProp { get; set; }...
}

public enum ValueType
{
    Range,
    State,
    Boolean
}

我最终得到了这个设计。。。在知道值类型之前,我需要有一些可以实例化的基础。我无法通过使用泛型来避免这种方法的麻烦(大量的铸造),并且也阻止了我拥有不可知论的基础。如果可能的话,我想看看如何在这个场景中提高界面的可用性

public class BaseThing
{
    public string Id { get; set; }        
    public IValueConfig Configuration { get; set; }
    public string CommonProp { get; set; }...
}

public interface IValueConfig
{
    ValueType Type { get; }
}

public class RangeVal : IValueConfig
{
    public ValueType Type => ValueType.Range;
    public double Value { get; set; }
    public string UniqueProp { get; set; }...
}

public class StateVal : IValueConfig
{
    public ValueType Type => ValueType.State;
    public string Value { get; set; }
    public string UniqueProp { get; set; }...
}

public class BooleanVal : IValueConfig
{
    public ValueType Type => ValueType.Boolean;
    public bool Value { get; set; }
    public string UniqueProp { get; set; }...
}

public enum ValueType
{
    Range,
    State,
    Boolean
}

您的意思是属性的类型不同,或者名称和属性都不同?听起来像是一个通用接口可以做到这一点。只是类型不同-属性名称在所有情况下都必须相同。如果没有关于如何准确使用这些类型的信息,就无法提供有用的答案,因此它会给您带来问题。由于您感兴趣的类型(string/long/bool)之间没有任何共同之处,因此很难提出可以普遍简化代码的建议。泛型(如建议的)不太可能有帮助,因为泛型方法使用的这些类型之间没有共同点……同意@AlexeiLevenkov。您是否希望能够将
属性放入接口
IThing
,并从接口访问它?关于“引导我走这条路的需求”的更多信息将有助于形成答案。您的意思是属性的类型会不同,或者名称和属性都会不同?听起来像是一个通用接口可以做到这一点。只是类型不同-属性名称在所有情况下都必须相同。如果没有关于如何准确使用这些类型的信息,就无法提供有用的答案,因此它会给您带来问题。由于您感兴趣的类型(string/long/bool)之间没有任何共同之处,因此很难提出可以普遍简化代码的建议。泛型(如建议的)不太可能有帮助,因为泛型方法使用的这些类型之间没有共同点……同意@AlexeiLevenkov。您是否希望能够将
属性放入接口
IThing
,并从接口访问它?关于“需求引导我走这条路”的更多信息将有助于形成答案。我怀疑这对OP来说毫无用处,因为他们似乎需要知道存储了什么类型的值。。。那些泛型本身根本不能消除。。。事实上,你可以检查/转换为稍微有点花哨的类型(
Thing
vs.
ThingA
),但这是否足够改进…@AlexeiLevenkov是的,没有进一步的澄清,很难猜测他使用的任何模式在哪里会出现问题。假设他的问题是他至少是什么意思,我怀疑这会奏效。当然,假设这些问题和答案有时会变得非常奇怪…我认为这个想法是使用接口来处理Value属性,但@AlexeiLevenkov对这种接口的实际可用性提出了一个很好的观点。我怀疑这对OP来说完全是无用的,因为他们似乎需要知道存储了什么类型的值。。。那些泛型本身根本不能消除。。。事实上,你可以检查/转换为稍微有点花哨的类型(
Thing
vs.
ThingA
),但这是否足够改进…@AlexeiLevenkov是的,没有进一步的澄清,很难猜测他使用的任何模式在哪里会出现问题。假设他的问题是他至少是什么意思,我怀疑这会奏效。当然,假设这些问题和答案有时会变得非常奇怪……我认为想法是使用接口来处理Value属性,但是@AlexeiLevenkov很好地说明了此类接口的实际可用性。