C# Can';t定义静态抽象字符串属性
我遇到了一个有趣的问题,正在寻找一些关于如何最好地处理这个问题的建议 我有一个抽象类,它包含一个静态方法,该方法接受一个我想定义为抽象属性的静态字符串。问题是C#不支持以下内容(请参阅配置部分名称和当前属性): 我想处理这个问题的一种方法是使ConfigurationSectionName不抽象,然后在派生类中创建ConfigurationSectionName的新定义,但这感觉很粗糙。欢迎提出任何建议C# Can';t定义静态抽象字符串属性,c#,.net,C#,.net,我遇到了一个有趣的问题,正在寻找一些关于如何最好地处理这个问题的建议 我有一个抽象类,它包含一个静态方法,该方法接受一个我想定义为抽象属性的静态字符串。问题是C#不支持以下内容(请参阅配置部分名称和当前属性): 我想处理这个问题的一种方法是使ConfigurationSectionName不抽象,然后在派生类中创建ConfigurationSectionName的新定义,但这感觉很粗糙。欢迎提出任何建议 感谢 静态成员没有多态性,因此它们不能是抽象的:( 如果这是你需要的,考虑创建一个对象,并从
感谢 静态成员没有多态性,因此它们不能是抽象的:(
如果这是你需要的,考虑创建一个对象,并从该对象中读取属性。
只使用<代码>新< /C> >在派生类中重写静态方法。不允许“<代码>新< /代码>”适用于虚拟方法和属性,因为必须提供类型名:public class BaseClass
{
public static int Max { get { return 0; } }
}
public class InteriorClass : BaseClass
{
}
public class DerivedClass : InteriorClass
{
public new static int Max { get { return BaseClass.Max + 1; } }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("BaseClass.Max = {0}", BaseClass.Max);
Console.WriteLine("InteriorClass.Max = {0}", InteriorClass.Max);
Console.WriteLine("DerivedClass.Max = {0}", DerivedClass.Max);
Console.ReadKey();
}
}
正如其他人所提到的,你试图做的是不可能的 我想试试这样的
public abstract class ProviderConfiguration : ConfigurationSection
{
public string ConfigurationSectionName { get; set; }
public static ProviderConfiguration Provider { get; set; }
public static Configuration Current
{
get { return (Configuration)ConfigurationManager.GetSection(Provider.ConfigurationSectionName); }
}
}
然后在实践中:
public void DoStuff()
{
var provider = new DerivedProviderConfiguration();
ProviderConfiguration.Provider = provider;
}
好的,这并不完全是为了创建一个静态抽象属性,但是您可以实现所需的效果 您可以通过使用泛型来实现这一点:
public abstract class MyAbstractClass<T>
{
public static string MyAbstractString{ get; set; }
public static string GetMyAbstracString()
{
return "Who are you? " + MyAbstractString;
}
}
public class MyDerivedClass : MyAbstractClass<MyDerivedClass>
{
public static new string MyAbstractString
{
get
{
return MyAbstractClass<MyDerivedClass>.MyAbstractString;
}
set
{
MyAbstractClass<MyDerivedClass>.MyAbstractString = value;
}
}
}
public class MyDerivedClassTwo : MyAbstractClass<MyDerivedClassTwo>
{
public static new string MyAbstractString
{
get
{
return MyAbstractClass<MyDerivedClassTwo>.MyAbstractString;
}
set
{
MyAbstractClass<MyDerivedClassTwo>.MyAbstractString = value;
}
}
}
public class Test
{
public void Test()
{
MyDerivedClass.MyAbstractString = "I am MyDerivedClass";
MyDerivedClassTwo.MyAbstractString = "I am MyDerivedClassTwo";
Debug.Print(MyDerivedClass.GetMyAbstracString());
Debug.Print(MyDerivedClassTwo.GetMyAbstracString());
}
}
公共抽象类MyAbstractClass
{
公共静态字符串MyAbstractString{get;set;}
公共静态字符串GetMyAbstracString()
{
返回“你是谁?”+MyAbstractString;
}
}
公共类MyDerivedClass:MyAbstractClass
{
公共静态新字符串MyAbstractString
{
得到
{
返回MyAbstractClass.MyAbstractString;
}
设置
{
MyAbstractClass.MyAbstractString=值;
}
}
}
公共类MyDerivedClass2:MyAbstractClass
{
公共静态新字符串MyAbstractString
{
得到
{
返回MyAbstractClass.MyAbstractString;
}
设置
{
MyAbstractClass.MyAbstractString=值;
}
}
}
公开课考试
{
公开无效测试()
{
MyDerivedClass.MyAbstractString=“我是MyDerivedClass”;
MyDerivedClass2.MyAbstractString=“我是MyDerivedClass2”;
Print(MyDerivedClass.GetMyAbstracString());
Print(myderivedclass2.GetMyAbstracString());
}
}
因此,调用您将得到的测试类:
“你是谁?我是我的班级”
“你是谁?我是MyderivedClass2”
因此,在抽象类中有一个静态方法,但是每个派生类的抽象值都不同,nice:D
好的,那么,这是怎么回事?诀窍是泛型标记,编译器为每个派生类型生成不同的抽象类
正如我所说,它不是一个抽象属性,但您可以从抽象静态属性中获得所有好处,即在抽象类上编程静态函数,但每种类型使用不同的静态参数。在本页其他地方,@Gusman这里提炼出了一个很好的解决方案:
abstract class AbstractBase { };
abstract class AbstractBase<T> : AbstractBase
{
public static String AbstractStaticProp { get; set; }
};
class Derived1 : AbstractBase<Derived1>
{
public static new String AbstractStaticProp
{
get => AbstractBase<Derived1>.AbstractStaticProp;
set => AbstractBase<Derived1>.AbstractStaticProp = value;
}
};
class Derived2 : AbstractBase<Derived2>
{
public static new String AbstractStaticProp
{
get => AbstractBase<Derived2>.AbstractStaticProp;
set => AbstractBase<Derived2>.AbstractStaticProp = value;
}
};
这消除了class-Derived2:AbstractBase{/*…*/}
的可能性,但没有消除错误class-Derived2:AbstractBase{/*…*/}
。这是由于一个反复出现的难题阻碍了将泛型类型约束到类型继承层次结构的某个确切分支的所有尝试:
问题“TSelf
问题”泛型约束总是由提供的类型参数决定,这似乎意味着不可能构造一个泛型约束来保证其范围内的某个特定
target
引用从自身派生的类型,即定义的直接类型
本例中的错误就是一个例子;虽然AbstractBase
上的约束排除了不兼容的不相交类型,但它不能排除意外使用Derived2:AbstractBase
。就AbstractBase
而言,提供的类型参数Derived1
很好地满足了它的约束,不管它的哪个子类型正确地派生了它自己(im-)。多年来,我尝试了所有方法来解决TSelf
;如果有人知道我错过的一个技巧,请告诉我
无论如何,还有几点需要提及。例如,除非您能立即在以下代码中发现问题,否则您必须同意这有点危险:
public static new String AbstractStaticProp
{
get => AbstractBase<Derived1>.AbstractStaticProp;
set => AbstractBase<Derived2>.AbstractStaticProp = value;
}
这与顶部的代码相同。测试线束给出的结果与之前相同
static void Test()
{
Derived1.AbstractStaticProp = "I am Derived1";
Derived2.AbstractStaticProp = "I am Derived2";
Debug.Print(Derived1.AbstractStaticProp); // --> I am Derived1
Debug.Print(Derived2.AbstractStaticProp); // --> I am Derived2
}
这是不可能的。你想做什么?可能重复的可能重复的可能重复的可能重复的不适用于goombaloon的示例。他的基类将期望派生类返回必要的值,但由于派生类将显示属性,因此基类将只能访问其自己的基实现选项。在不依赖派生实现的情况下实现行为的静态属性是需要使用“new”重新实现的属性,在本例中为“public static new Configuration Current”。这使得基本节名称除了organization之外没有任何实际用途。谢谢。在我更详细地回顾了我试图实现的内容之后(经过一段时间的睡眠之后),答案变得更清楚了,那就是:(确实如此。这对OP来说并不重要,但对于记录来说,这种方法有一个典型的竞争条件。当多个
ProviderConfiguration
具体实例竞争基类中的静态Provider
属性时,它们可能会在DoStuff
函数的两行之间错误地交错。
public static new String AbstractStaticProp
{
get => AbstractBase<Derived1>.AbstractStaticProp;
set => AbstractBase<Derived2>.AbstractStaticProp = value;
}
abstract class AbstractBase { };
abstract class AbstractBase<TSelf> : AbstractBase
where TSelf : AbstractBase<TSelf>
{
public static String AbstractStaticProp { get; set; }
};
class Derived1 : AbstractBase<Derived1> { };
class Derived2 : AbstractBase<Derived2> { };
static void Test()
{
Derived1.AbstractStaticProp = "I am Derived1";
Derived2.AbstractStaticProp = "I am Derived2";
Debug.Print(Derived1.AbstractStaticProp); // --> I am Derived1
Debug.Print(Derived2.AbstractStaticProp); // --> I am Derived2
}