在 JavaScript 稀疏数组和 C#(稀疏)数组之间映射的推荐方法?

发布于 2024-08-06 01:55:01 字数 123 浏览 14 评论 0原文

我正在尝试将 JavaScript 稀疏数组映射到 C# 表示形式。

推荐的方法是什么?

它正在考虑使用包含原始数组中包含值的序号列表的字典。

还有其他想法吗?

谢谢!

I am trying to map a JavaScript sparse array to a C# representation.

What is the recommended way of doing this?

It am considering using a dictionary containing the list of oridinals that contained a value in the original array.

Any other ideas?

thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泪眸﹌ 2024-08-13 01:55:01

注意

对于这种情况,我提出了两种 .NET 解决方案。由于这两种解决方案都需要相同的 JavaScript 代码,因此我在此答案中仅包含这 2 个解决方案的 JavaScript 代码。

现在来回答...


编辑说明:对于一开始没有完全理解您的问题,我深表歉意。我以前从未听说过“稀疏数组”这个术语,所以我不得不查找它并找到了教科书 维基百科的定义,这并不完全是您所描述的,而且就我从那时起在其他地方看到的用法而言,似乎也不是您所描述的。然而,以这种方式使用它确实有意义。

更多地思考这个场景促使我想出一个解决方案。正如您所提到的,除了 null 之外,C#(以及一般的 .NET)没有 undefined 的概念。

据我了解,您希望能够在数组中表示三个不同的事物:

  • 数组元素的有效值
  • 数组元素的空值
  • “未定义”数组元素的概念

正如您所指出的,C#除了 null 之外,没有“未定义”的概念。对于 .NET,undefinednull 相同,并且可能应该保持这种方式。但是,由于您显然需要一种方法来表示这一点(我假设有一些奇怪的业务规则),所以我试图想出一个可行的实现。但我强烈建议不要这样做!

JavaScript 方面

第一个挑战是在 JavaScript 中序列化数组的行为。将数组转换为 JSON 格式时,数组中的 undefined 元素会自动转换为 null。如果您调用 JSON.stringify(...),就会发生这种情况:

var array = [73,42,undefined,null,23];
var json = JSON.stringify(array);
if(json === "[73,42,null,null,23]")
    alert('I am always true!');

上面的示例显示数组中未定义的元素被序列化为“null”。如果您确实需要存储未定义的元素,则必须编写一个转换方法来手动序列化数组以包​​含未定义的元素。理想的解决方案将产生以下 JSON:

"[73,42,undefined,null,23]"

但是,这是行不通的。 .NET JavaScriptSerializerJSON.parse(...) 都无法解析此字符串(尽管 JavaScript 的 eval(...) 方法工作)。我们需要的是一种表示“undefined”的方法,该方法将使用标准 JSON 方法进行序列化,并且可以被 .NET 的 JavaScriptSerializer 理解。做到这一点的技巧是提出一个实际的对象来表示未定义。为了表示这一点,我使用了这个 JSON 字符串:

"{undefined:null}"

一个对象,其唯一属性称为“undefined”,其值为 null。这很可能不会存在于 JavaScript 代码中的任何对象中,因此我使用它是因为我认为它是一个足够“唯一”的标志来表示我们不存在的“未定义”数组元素。

要像这样序列化 JSON,您需要提供一个替换器来完成这项工作,因此您可以这样做:

var arr = [73,42,undefined,null,23];
var json = JSON.stringify(arr, function(key, value) {
    jsonArray = value;
    if(value instanceof Array) {    
        var jsonArray = "[";
        for(var i = 0; i < value.length; i++) {
            var val = value[i];
            if(typeof val === "undefined") {
                jsonArray += "{undefined:null}";
            } else {
                jsonArray += JSON.stringify(value[i]);
            }
            if(i < value.length - 1) {
                jsonArray += ",";
            }
        }
        jsonArray += "]";
        if(key != null && key != "") {
            return key + ":" + jsonArray;
        } else {
            return jsonArray;
        }
    }
    
    if(key != null && key != "") {
        return key + ":" + JSON.stringify(jsonArray);
    } else {
        return JSON.stringify(jsonArray);
    }
});

这将为您提供一个如下所示的 JSON 字符串:

"[73,42,{undefined:null},null,23]"

这样做的缺点是一旦反序列化,undefined数组元素不再是undefined,而是另一个对象。这意味着您的解析器必须专门处理这个问题。确保您不要尝试在任何不知道完全组成的“未定义”对象的 JSON 解析器中使用它。下一步是用 C# 处理它。


C# 方面

这里的挑战是如何表示未定义的值。下面的解决方案选择将数组中未定义的索引视为“不存在”。我的另一个解决方案创建一个类似于结构的 Nullable 包装器的包装器。

创建 SparseArray 字典包装器

我创建了一个 SparseArray 类,可以像 .NET 中的普通数组一样使用它。这个类和类之间的区别普通数组的特点是,当您访问未定义的数组元素时,它会抛出自定义的 IndexNotFoundException。您可以通过首先调用 SparseArray.ContainsIndex(index) 检查元素是否已定义来避免引发此异常,以检查它是否具有该索引。

正如您在问题中提到的,它在内部使用字典。初始化它时,构造函数首先获取 JSON 字符串并通过 JavaScriptSerializer 运行它。

然后,它获取反序列化的数组并开始将每个数组元素添加到其 _Array 字典中。当它添加元素时,当我们“串通”它时,它会查找我们在 JavaScript 中定义的 {undefined:null} 对象(不确定这是否是正确的过去时态......)。如果它看到这个对象,索引就会被跳过。当发现未定义的值时,数组的长度将增加,但它们的索引将被跳过。

由于类的代码相当长,我将首先放置使用示例:

string json = "[4,5,null,62,{undefined:null},1,68,null, 3]";
SparseArray<int?> arr = new SparseArray<int?>(json);

for { } 循环中,您需要在访问数组之前检查数组是否包含每个索引。在 foreach { } 循环中,枚举器仅保存已定义的值,因此您无需担心出现 未定义 值。

这是我的 SparseArray 类的代码:

[DebuggerDisplay("Count = {Count}")]
public class SparseArray<T>: IList<T>
{
    Dictionary<int, T> _Array = new Dictionary<int, T>();
    int _Length = 0;

    public SparseArray(string jsonArray)
    {
        var jss = new JavaScriptSerializer();
        var objs = jss.Deserialize<object[]>(jsonArray);
        
        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i] is Dictionary<string, object>)
            {
                // If the undefined object {undefined:null} is found, don't add the element
                var undefined = (Dictionary<string, object>)objs[i];
                if (undefined.ContainsKey("undefined") && undefined["undefined"] == null)
                {
                    _Length++;
                    continue;
                }
            }
            T val;
            // The object being must be serializable by the JavaScriptSerializer
            // Or at the very least, be convertible from one type to another
            // by implementing IConvertible.
            try
            {
                val = (T)objs[i];
            }
            catch (InvalidCastException)
            {
                val = (T)Convert.ChangeType(objs[i], typeof(T));
            }

            _Array.Add(_Length, val);
            _Length++;
        }
    }

    public SparseArray(int length)
    {
        // Initializes the array so it behaves the same way as a standard array when initialized.
        for (int i = 0; i < length; i++)
        {
            _Array.Add(i, default(T));
        }
        _Length = length;
    }

    public bool ContainsIndex(int index)
    {
        return _Array.ContainsKey(index);
    }


    #region IList<T> Members

    public int IndexOf(T item)
    {
        foreach (KeyValuePair<int, T> pair in _Array)
        {
            if (pair.Value.Equals(item))
                return pair.Key;
        }
        return -1;
    }

    public T this[int index]
    {
        get {
            if (_Array.ContainsKey(index))
                return _Array[index];
            else
                throw new IndexNotFoundException(index);
        }
        set { _Array[index] = value; }
    }              

    public void Insert(int index, T item)
    {
        throw new NotImplementedException();
    }

    public void RemoveAt(int index)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region ICollection<T> Members

    public void Add(T item)
    {
        _Array.Add(_Length, item);
        _Length++;
    }

    public void Clear()
    {
        _Array.Clear();
        _Length = 0;
    }

    public bool Contains(T item)
    {
        return _Array.ContainsValue(item);
    }        

    public int Count
    {
        get { return _Length; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(T item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return _Array.Values.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _Array.Values.GetEnumerator();
    }

    #endregion
}

以及使用此类所需的异常:

public class IndexNotFoundException:Exception
{
    public IndexNotFoundException() { }
    public IndexNotFoundException(int index) 
          : base(string.Format("Array is undefined at position [{0}]", index)) 
    { 
    }
}

NOTE

I've come up with two .NET solutions to this scenario. Because both solutions require the same JavaScript code, I've only included the JavaScript code for the 2 solutions in this answer.

Now on to the answer...


EDIT Note: I apologize for not completely understanding your question at first. I never heard the term "Sparse Array" used before, so I had to look it up and found the text book definition from Wikipedia, which isn't quite what you were describing and, as far as usage I've seen elsewhere since then, doesn't seem to be what you were describing. It does make sense to use it in this way however.

Thinking about this scenario more has driven me to come up with a solution. As you mentioned, C# (and .NET in general) has no concept of undefined, other than null.

From what I understand, you're looking to be able to represent three different things in your array:

  • A valid value for the array element
  • A null value for the array element
  • The concept of an "undefined" array element

As you pointed out, C# has no concept of "undefined", other than null. To .NET, undefined would be the same as null and it probably should be kept that way. But since you obviously need a way to represent this anyway (I'm assuming for some strange business rule), I tried to come up with an implementation that will work. I'd strongly recommend not doing this though!

The JavaScript Side

The first challenge is the act of serializing the array in JavaScript. When converting an array to JSON format, undefined elements in an array are automatically converted to null. If you call JSON.stringify(...), this will happen:

var array = [73,42,undefined,null,23];
var json = JSON.stringify(array);
if(json === "[73,42,null,null,23]")
    alert('I am always true!');

The example above shows that undefined elements in the array are serialized as "null". If you really need to store undefined, you'd have to write a conversion method that will manually serialize arrays to have undefined elements. The ideal solution would result in this JSON:

"[73,42,undefined,null,23]"

This will not work however. Neither the .NET JavaScriptSerializer, or JSON.parse(...) can parse this string (although JavaScript's eval(...) method will work). What we need is a way to represent "undefined" that will serialize using standard JSON methods, and can be understood by .NET's JavaScriptSerializer. The trick to doing this is coming up with an actual object to represent undefined. To represent this, I used this JSON string:

"{undefined:null}"

An object whose only property is called "undefined", and whose value is null. This most likely will not exist in any object in JavaScript code so I'm using this as I consider it a "unique" enough flag to represent our non-existent "undefined" array element.

To serialize JSON like this, you need to provide a replacer that will do the job, so here is how you'd do that:

var arr = [73,42,undefined,null,23];
var json = JSON.stringify(arr, function(key, value) {
    jsonArray = value;
    if(value instanceof Array) {    
        var jsonArray = "[";
        for(var i = 0; i < value.length; i++) {
            var val = value[i];
            if(typeof val === "undefined") {
                jsonArray += "{undefined:null}";
            } else {
                jsonArray += JSON.stringify(value[i]);
            }
            if(i < value.length - 1) {
                jsonArray += ",";
            }
        }
        jsonArray += "]";
        if(key != null && key != "") {
            return key + ":" + jsonArray;
        } else {
            return jsonArray;
        }
    }
    
    if(key != null && key != "") {
        return key + ":" + JSON.stringify(jsonArray);
    } else {
        return JSON.stringify(jsonArray);
    }
});

This will get you a JSON string that looks like this:

"[73,42,{undefined:null},null,23]"

The downside to this is that once it is deserialized, the undefined array element is no longer undefined, but another object. This means that your parser will have to handle this specially. Make sure that you don't try to use this in any JSON parser that isn't aware of the completely made up "undefined" object. The next step is handle it in C#.


The C# Side

The challenge here is how to represent Undefined values. The solution below opts to treat undefined indexes as "non-existent" in an array. My other solution creates a wrapper similar to the Nullable<T> wrapper for structs.

Create a SparseArray<T> Dictionary Wrapper

I created a SparseArray<T> class that can be used just like a normal array in .NET. The difference between this class & a normal array is that when you access an array element which is undefined, it throws a custom IndexNotFoundException. You can avoid throwing this exception by first checking if the element is defined by calling SparseArray<T>.ContainsIndex(index) to check if it has that index.

Internally it uses a Dictionary, as you mentioned in your question. When you initialize it, first the constructor takes the JSON string and runs it through a JavaScriptSerializer.

It then takes the deserialized array and begins to add each array element to its _Array dictionary. As it adds elemnts, it looks for the {undefined:null} object we defined in JavaScript when we "strungified" it (not sure if that's the correct past tense there...). If it sees this object, the index is skipped over. The length of the array will increment as undefined values are found, however their index is skipped over.

Since the class' code is rather long, I'll put the usage example first:

string json = "[4,5,null,62,{undefined:null},1,68,null, 3]";
SparseArray<int?> arr = new SparseArray<int?>(json);

In a for { } loop, you'll need to check if the array contains each index before accessing it. In a foreach { } loop, the enumerator holds only defined values, so you won't need to worry about the occurrence of undefined values.

Here is the code for my SparseArray<T> class:

[DebuggerDisplay("Count = {Count}")]
public class SparseArray<T>: IList<T>
{
    Dictionary<int, T> _Array = new Dictionary<int, T>();
    int _Length = 0;

    public SparseArray(string jsonArray)
    {
        var jss = new JavaScriptSerializer();
        var objs = jss.Deserialize<object[]>(jsonArray);
        
        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i] is Dictionary<string, object>)
            {
                // If the undefined object {undefined:null} is found, don't add the element
                var undefined = (Dictionary<string, object>)objs[i];
                if (undefined.ContainsKey("undefined") && undefined["undefined"] == null)
                {
                    _Length++;
                    continue;
                }
            }
            T val;
            // The object being must be serializable by the JavaScriptSerializer
            // Or at the very least, be convertible from one type to another
            // by implementing IConvertible.
            try
            {
                val = (T)objs[i];
            }
            catch (InvalidCastException)
            {
                val = (T)Convert.ChangeType(objs[i], typeof(T));
            }

            _Array.Add(_Length, val);
            _Length++;
        }
    }

    public SparseArray(int length)
    {
        // Initializes the array so it behaves the same way as a standard array when initialized.
        for (int i = 0; i < length; i++)
        {
            _Array.Add(i, default(T));
        }
        _Length = length;
    }

    public bool ContainsIndex(int index)
    {
        return _Array.ContainsKey(index);
    }


    #region IList<T> Members

    public int IndexOf(T item)
    {
        foreach (KeyValuePair<int, T> pair in _Array)
        {
            if (pair.Value.Equals(item))
                return pair.Key;
        }
        return -1;
    }

    public T this[int index]
    {
        get {
            if (_Array.ContainsKey(index))
                return _Array[index];
            else
                throw new IndexNotFoundException(index);
        }
        set { _Array[index] = value; }
    }              

    public void Insert(int index, T item)
    {
        throw new NotImplementedException();
    }

    public void RemoveAt(int index)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region ICollection<T> Members

    public void Add(T item)
    {
        _Array.Add(_Length, item);
        _Length++;
    }

    public void Clear()
    {
        _Array.Clear();
        _Length = 0;
    }

    public bool Contains(T item)
    {
        return _Array.ContainsValue(item);
    }        

    public int Count
    {
        get { return _Length; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(T item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return _Array.Values.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _Array.Values.GetEnumerator();
    }

    #endregion
}

And the exception needed to use this class:

public class IndexNotFoundException:Exception
{
    public IndexNotFoundException() { }
    public IndexNotFoundException(int index) 
          : base(string.Format("Array is undefined at position [{0}]", index)) 
    { 
    }
}
心舞飞扬 2024-08-13 01:55:01

注意

对于这种情况,我提出了两种 .NET 解决方案。我将它们保存在单独的答案中,以便可以根据哪个解决方案更有利对它们进行投票,以便作者可以选择最有利的解决方案作为“接受的答案”。由于这两种解决方案都需要相同的 JavaScript 代码,因此我在其他答案中仅包含了这 2 个解决方案的 JavaScript 代码。如果此答案被标记为已接受,我将在此答案中包含我的 JavaScript 解决方案,以便它将包含在页面上逻辑上第一个出现的答案中。

现在来回答......


首先,我想重复我在其他解决方案中提到的内容,因为值得一提的是:

正如您所指出的,除了 null 之外,C# 没有“未定义”的概念。对于 .NET,undefinednull 相同,并且可能应该保持这种方式。但是,由于您显然需要一种方法来表示这一点(我假设有一些奇怪的业务规则),所以我试图想出一个可行的实现。但我强烈建议不要这样做!

对于此解决方案,我创建了一个名为 Undefined 的包装类。它的工作原理与 .NET 的本机 Nullable 类似。这样做的缺点是,由于 .NET 没有“未定义”的概念,因此很难决定如何处理对象值的访问。如果您尝试在未定义 对象时强制转换未定义 对象,我选择抛出异常。

通过此解决方案,您将拥有一个每个元素都存在的实际数组。尽管每个元素都存在,但您实际上无法获取每个元素的值。我创建的类在各方面的行为都类似于 Nullable,但当您尝试强制转换未定义的对象或获取其 Value 时,该类会引发异常。在实际尝试使用 Value 之前,您需要调用 IsDefined 以确保可以使用它。

[DebuggerDisplay("IsDefined:{IsDefined}, Value:{_Value}")]
public sealed class Undefined<T>
{
    public static Undefined<T>[] DeserializeArray(string jsonArray)
    {
        var jss = new JavaScriptSerializer();
        var objs = jss.Deserialize<object[]>(jsonArray);
        var undefinedArray = new Undefined<T>[objs.Length];

        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i] is Dictionary<string, object>)
            {
                var undefined = (Dictionary<string, object>)objs[i];
                if (undefined.ContainsKey("undefined") && undefined["undefined"] == null)
                {
                    undefinedArray[i] = new Undefined<T>(default(T), false);
                    continue;
                }
            }
            T val;
            // The object being must be serializable by the JavaScriptSerializer
            // Or at the very least, be convertible from one type to another
            // by implementing IConvertible.
            try
            {
                val = (T)objs[i];
            }
            catch (InvalidCastException)
            {
                val = (T)Convert.ChangeType(objs[i], typeof(T));
            }

            undefinedArray[i] = new Undefined<T>(val, true);
        }

        return undefinedArray;

    }

    private Undefined(T value, bool isDefined)
    {
        Value = value;
        IsDefined = isDefined;
    }

    public static explicit operator T(Undefined<T> value)
    {
        if (!value.IsDefined)
            throw new InvalidCastException("Value is undefined. Unable to cast.");
        return value.Value;
    }

    public bool IsDefined { get; private set; }

    private T _Value;
    public T Value
    {
        get
        {
            if (IsDefined)
                return _Value;
            throw new Exception("Value is undefined.");
        }
        private set { _Value = value; }
    }

    public override bool Equals(object other)
    {
        Undefined<T> o = other as Undefined<T>;
        if (o == null)
            return false;
        if ((!this.IsDefined && o.IsDefined) || this.IsDefined && !o.IsDefined)
            return false;
        return this.Value.Equals(o.Value);
    }

    public override int GetHashCode()
    {
        if (IsDefined)
            return Value.GetHashCode();
        return base.GetHashCode();
    }

    public T GetValueOrDefault()
    {
        return GetValueOrDefault(default(T));
    }

    public T GetValueOrDefault(T defaultValue)
    {
        if (IsDefined)
            return Value;
        return defaultValue;
    }

    public override string ToString()
    {
        if (IsDefined)
            Value.ToString();
        return base.ToString();
    }
} 

NOTE

I've come up with two .NET solutions to this scenario. I've kept them in separate answers so they could be voted on based on which solution is more favorable, and so that the author may choose the most favorable solution as the "Accepted Answer". Because both solutions require the same JavaScript code, I've only included the JavaScript code for the 2 solutions in my other answer. If this answer is marked as accepted, I'll include my JavaScript solution in this answer so that it will be included with the answer that comes logically first on the page.

Now on to the answer...


To start, I want to repeat what I mentioned in my other solution, since it is important to mention:

As you pointed out, C# has no concept of "undefined", other than null. To .NET, undefined would be the same as null and it probably should be kept that way. But since you obviously need a way to represent this anyway (I'm assuming for some strange business rule), I tried to come up with an implementation that will work. I'd strongly recommend not doing this though!

For this solution, I created a wrapper class called Undefined<T>. It works similarly to .NET's native Nullable<T>. The downside to this is that, because .NET has no concept of "undefined", it was difficult to decide how to handle accessing the value of the object. I chose to throw an exception if you try to cast an undefined object when it is undefined.

With this solution, you have an actual array where every element exists. Although every element exists, you can't actually get the value of every element. The class I created behaves like Nullable<T> in every way, except that when you try to cast an undefined object, or get its Value, this class throws an exception. You need to call IsDefined to make sure you can use the Value before you actually try to use it.

[DebuggerDisplay("IsDefined:{IsDefined}, Value:{_Value}")]
public sealed class Undefined<T>
{
    public static Undefined<T>[] DeserializeArray(string jsonArray)
    {
        var jss = new JavaScriptSerializer();
        var objs = jss.Deserialize<object[]>(jsonArray);
        var undefinedArray = new Undefined<T>[objs.Length];

        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i] is Dictionary<string, object>)
            {
                var undefined = (Dictionary<string, object>)objs[i];
                if (undefined.ContainsKey("undefined") && undefined["undefined"] == null)
                {
                    undefinedArray[i] = new Undefined<T>(default(T), false);
                    continue;
                }
            }
            T val;
            // The object being must be serializable by the JavaScriptSerializer
            // Or at the very least, be convertible from one type to another
            // by implementing IConvertible.
            try
            {
                val = (T)objs[i];
            }
            catch (InvalidCastException)
            {
                val = (T)Convert.ChangeType(objs[i], typeof(T));
            }

            undefinedArray[i] = new Undefined<T>(val, true);
        }

        return undefinedArray;

    }

    private Undefined(T value, bool isDefined)
    {
        Value = value;
        IsDefined = isDefined;
    }

    public static explicit operator T(Undefined<T> value)
    {
        if (!value.IsDefined)
            throw new InvalidCastException("Value is undefined. Unable to cast.");
        return value.Value;
    }

    public bool IsDefined { get; private set; }

    private T _Value;
    public T Value
    {
        get
        {
            if (IsDefined)
                return _Value;
            throw new Exception("Value is undefined.");
        }
        private set { _Value = value; }
    }

    public override bool Equals(object other)
    {
        Undefined<T> o = other as Undefined<T>;
        if (o == null)
            return false;
        if ((!this.IsDefined && o.IsDefined) || this.IsDefined && !o.IsDefined)
            return false;
        return this.Value.Equals(o.Value);
    }

    public override int GetHashCode()
    {
        if (IsDefined)
            return Value.GetHashCode();
        return base.GetHashCode();
    }

    public T GetValueOrDefault()
    {
        return GetValueOrDefault(default(T));
    }

    public T GetValueOrDefault(T defaultValue)
    {
        if (IsDefined)
            return Value;
        return defaultValue;
    }

    public override string ToString()
    {
        if (IsDefined)
            Value.ToString();
        return base.ToString();
    }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文