我已经使用隐式运算符创建了一个自定义数据类型,下面是示例代码。当我将硬编码值设置为自定义数据类型时,其按预期方式工作,但是使用反射抛出转换错误来设置值。(System.ArgumentException:'类型为'System.String'的对象不能转换为类型'TF.DataType.TFDiplay'。']
有人可以帮助我进行必要的更改以使其在思考中很好地工作
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TF.DataType
{
public class TFDiplay
{
public TFDiplay() { }
public TFDiplay(object value, string text) { Value = value; Text = text; }
public TFDiplay(object value)
{
Value = value;
}
public static implicit operator TFDiplay(string value)
{
var result = new TFDiplay()
{
Value = value
};
return result;
}
public static implicit operator TFDiplay(int value)
{
var result = new TFDiplay()
{
Value = value
};
return result;
}
public object Value { get; set; }
public string Text { get; set; }
}
}
class Program
{
static void Main(string[] args)
{
TFDiplay tFDiplay;
tFDiplay = "ss"; //Working as expected
tFDiplay = 1; //Working as expected
testDatatype t = new testDatatype();
Type s = t.GetType();
PropertyInfo p = s.GetProperty("Flag");
p.SetValue(t, "ss"); //Throwing error
}
public class testDatatype
{
public TFDiplay Flag { get; set; }
}
}
问题是,您不能通过反射将字符串分配给TFDiplay类型。反射不使用隐式转换器。隐式转换器是compiletype。反射是运行时。
突出显示:
TFDiplay tFDiplay;
tFDiplay = "ss"; //Working as expected
tFDiplay = 1; //Working as expected
隐式运算符为您完成工作。每次将字符串或整数分配给tFDiplay时,都会调用该运算符,然后会启动一个新的TFDisplay。因此,对现有对象调用运算符是没有用的。
这也是分配新实例时不必启动新实例的原因。
这里是有效的反射代码:
using System;
using System.Reflection;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
TFDiplay tFDiplay;
tFDiplay = "ss"; //Working as expected
tFDiplay = 1; //Working as expected
// ----
// create an instance of testDatatype
testDatatype testDatatype = new testDatatype();
Type testDatatypeType = testDatatype.GetType();
PropertyInfo flagProperty = testDatatypeType.GetProperty("Flag");
// you need to get the value of the flag..
var flagInstance = flagProperty.GetValue(testDatatype);
Type flagType = flagInstance.GetType();
PropertyInfo valueProperty = flagType.GetProperty("Value");
valueProperty.SetValue(flagInstance, "ss");
}
}
public class testDatatype
{
// notice that I create an instance here:
public TFDiplay Flag { get; } = new TFDiplay();
}
public class TFDiplay
{
public TFDiplay() { }
public TFDiplay(object value, string text) { Value = value; Text = text; }
public TFDiplay(object value)
{
Value = value;
}
public static implicit operator TFDiplay(string value)
{
var result = new TFDiplay()
{
Value = value
};
return result;
}
public static implicit operator TFDiplay(int value)
{
var result = new TFDiplay()
{
Value = value
};
return result;
}
public object Value { get; set; }
public string Text { get; set; }
}
}
扩展Jeroen的答案:
隐式运算符会生成一个称为op_Implicit
的特殊方法。要使用隐式运算符正确地“广播”,可以使用反射调用该方法:
var op = typeof(TFDiplay).GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static,
null, new[] { typeof(string) }, null);
tFDiplay = (TFDiplay)op.Invoke(null, new object[] { "ss" });