【问题标题】:C# Properties based on choice基于选择的 C# 属性
【发布时间】:2013-07-24 07:19:26
【问题描述】:

我需要一点帮助,我正在使用一个类,并希望根据类型 int、string 和 datetime 的选择来设置属性 这是我编写的代码,但由于我的构造函数会在公共字符串 paramValue 和公共 int 之间混淆? paramValue 根据选择设置属性的最佳方法是什么,因此一次只能设置一个属性。感谢您的任何建议

public class PassData
{
    private string _ParamName { get; set; }
    private int? _ParamValueInt { get; set; }
    private string _ParamValueString { get; set; }
    private DateTime? _ParamValueDateTime { get; set; }


    public string paramName
    {
        get { return _ParamName; }
        set { _ParamName = value;}
    }

    public string paramValue
    {
        get { return _ParamValueString; }
        set {_ParamValueString = value; }
    }

    public int? paramValue
    {
        get { return _ParamValueInt; }
        set { _ParamValueInt = value; }
    }

    public PassData(string ParamName, int ParamValue)
    {
        paramName = ParamName;
        paramValue = ParamValue;
    }
    public PassData(string ParamName, string ParamValue)
    {
        ParamName = ParamName;
        ParamValueString = ParamValue;
    }
    public PassData(string ParamName, DateTime ParamValue)
    {
        ParamName = ParamName;
        ParamValueDateTime = ParamValue;
    }
}

【问题讨论】:

  • 您的代码无法编译。您不能有 2 个具有相同名称的属性。如果可以的话,你不应该。想出好名字很难,但它是成功的一半。它将防止这成为一个问题。
  • 您不能使用两种不同的返回类型两次声明相同的属性名称。
  • 你对属性和参数的使用有点困惑。
  • 为什么不简单地public class PassData<TDataType> { public TDataType Value {get;set;} }
  • 您的私有成员通常应该是参数,而不是属性。同样,这并不重要,但是您的大写约定是倒退的。公共属性通常是 Pascal 大写 (public string ParamValue),而私有参数通常是 Camel 大写 (private string _paramValue) - 带或不带下划线

标签: c# .net


【解决方案1】:

基本上,您不能在一个对象上拥有多个仅在类型上有所不同的属性。你有几个选择。

1) 创建一个可以容纳各种类型的属性:

private Object _paramValue;
public Object ParamValue
{
   get { return _paramValue; }
   set {_paramValue= value; }
}

在您的设置器中,如果值是您不喜欢的类型,您可以抛出异常。每次调用 getter 时,您还必须 upcast 结果,这使得该解决方案并不理想。如果你想走这条路,我建议将属性设为接口,并为你需要的数据类型定义各种实现。

2) 创建一个泛型类:

public class PassData<T>
{
   private T _paramValue;
   public T paramValue
   {
      get { return _paramValue; }
      set {_paramValue= value; }
   }
}

这样做的缺点是在创建实例后无法更改类型。不清楚这是否是您的要求。

我喜欢这种设计,因为它提供了将此类的构造函数设为私有的可能性:

public class PassData<T>
{
   private PassData(T value)
   {
      this._paramValue = value;
   }
}

如果你这样做了,你可以创建重载的静态方法来允许创建实例:

public static PassData<String> CreateValue(string value)
{
   return new PassData<String>(value);
}

public static PassData<Int32> CreateValue(Int32 value)
{
   return new PassData<Int32>(value);
}

这样,您可以控制可以创建的类型。

【讨论】:

  • 谢谢 Mike 让我试试你的方法。+1 为第一个答案
  • 静态方法需要一个泛型类型参数。
  • @MikeChristensen 我理解你想要做什么,但就目前而言,这不会编译。 Using the generic type 'UserQuery.PassData&lt;T&gt;' requires 1 type arguments
【解决方案2】:

不是答案(从某种意义上说,它没有为您提供一种方法来做您想做的事情,正如 Mike Christensen 的回答所涵盖的那样)。我只是想更多地了解为什么您尝试做的事情不起作用。 您对其工作的期望本身并不是不合理的,问题是 c# 在返回值上不是多态的。我认为其他一些语言是,C# 不是。

即在 c# 中,您可以这样做:

public void test(int val) {}
public void test(string val) {}
// When you call `test` with either an int or a string, 
// the compiler will know which one to call

你不能这样做:

public int test() {return 1;}
public string test() {return "1";}
// does not compile. The compiler should look at the call
// site and see what you assign the result of "test()" to
// to decide. But there are various edge cases and it was decided
// to leave this out of the language

现在,string paramValue 上的 get 在功能上等同于这种情况。您正试图让编译器根据返回值决定调用哪个 paramValue。

【讨论】:

  • +1 提供好的建议并为我提供知识。我可能需要深入阅读 C#。
  • @Pamma 顺便说一句,如果你想表达一个可以包含字符串或 int 或 DateTime 的类型,你可能想看看这个问题的公认答案:@ 987654321@(也可以查看 cmets,其中 Juliet 提供了一个更漂亮的选择,IMO)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 2012-05-12
  • 2023-03-06
  • 2012-05-14
相关资源
最近更新 更多